diff --git a/.gitignore b/.gitignore index 2e20e0d..da695ab 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,5 @@ dist/ release/ test/integration/src/ src/lib/*.js -src/js/crypto/aes-cbc.js -src/js/crypto/crypto-batch.js -src/js/crypto/rsa.js +src/js/crypto/aes-gcm.js src/js/crypto/util.js diff --git a/Gruntfile.js b/Gruntfile.js index 689e53b..98dd472 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -44,29 +44,17 @@ module.exports = function(grunt) { }, jshint: { - all: ['Gruntfile.js', 'src/*.js', 'src/js/**/*.js', 'test/new-unit/*.js', 'test/unit/*.js', 'test/integration/*.js'], + all: ['Gruntfile.js', 'src/*.js', 'src/js/**/*.js', 'test/unit/*.js', 'test/integration/*.js'], options: { jshintrc: '.jshintrc' } }, - qunit: { - all: { - options: { - timeout: 20000, - urls: ['http://localhost:<%= connect.test.options.port %>/test/unit/index.html' - /*, - 'http://localhost:<%= connect.test.options.port %>/test/integration/index.html'*/ - ] - } - } - }, - mocha: { all: { options: { urls: [ - 'http://localhost:<%= connect.test.options.port %>/test/new-unit/index.html', + 'http://localhost:<%= connect.test.options.port %>/test/unit/index.html', 'http://localhost:<%= connect.test.options.port %>/test/integration/index.html' ], run: false, @@ -255,7 +243,6 @@ module.exports = function(grunt) { // Load the plugin(s) grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-qunit'); grunt.loadNpmTasks('grunt-mocha'); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-csso'); diff --git a/README.md b/README.md index 32b3bfa..2b42fcf 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ We take the privacy of your data very seriously. Here are some of the technical You can download a prebuilt bundle under [releases](https://github.com/whiteout-io/mail-html5/releases) or build your own from source (requires [node.js](http://nodejs.org/download/), [grunt](http://gruntjs.com/getting-started#installing-the-cli) and [sass](http://sass-lang.com/install)): npm install && npm test - + This will download all dependencies, run the tests and build the Chrome Packaged App bundle **DEV.zip** which can be installed under [chrome://extensions](chrome://extensions) in developer mode. ### Development @@ -40,7 +40,7 @@ For development you can start a connect dev server: grunt dev -Then visit [http://localhost:8580/dist/chrome.html#/desktop](http://localhost:8580/dist/chrome.html#/desktop) for front-end code or [http://localhost:8580/test/new-unit/](http://localhost:8580/test/new-unit/) to test JavaScript changes. You can also start a watch task so you don't have rebuild everytime you make a change: +Then visit [http://localhost:8580/dist/chrome.html#/desktop](http://localhost:8580/dist/chrome.html#/desktop) for front-end code or [http://localhost:8580/test/unit/](http://localhost:8580/test/unit/) to test JavaScript changes. You can also start a watch task so you don't have rebuild everytime you make a change: grunt watch diff --git a/package.json b/package.json index 4718407..676c51e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "start": "grunt && grunt dev" }, "dependencies": { - "crypto-lib": "https://github.com/whiteout-io/crypto-lib/tarball/v0.1.1", + "crypto-lib": "https://github.com/whiteout-io/crypto-lib/tarball/v0.2.0", "imap-client": "https://github.com/whiteout-io/imap-client/tarball/v0.3.3", "mailreader": "https://github.com/whiteout-io/mailreader/tarball/v0.3.3", "pgpmailer": "https://github.com/whiteout-io/pgpmailer/tarball/v0.3.4", @@ -27,7 +27,6 @@ "sinon": "~1.7.3", "grunt-contrib-connect": "~0.5.0", "grunt-contrib-jshint": "~0.6.4", - "grunt-contrib-qunit": "~0.2.2", "grunt-mocha": "~0.4.1", "grunt-contrib-clean": "~0.5.0", "grunt-csso": "~0.6.1", diff --git a/src/js/app-config.js b/src/js/app-config.js index e6df9f4..b841d80 100644 --- a/src/js/app-config.js +++ b/src/js/app-config.js @@ -25,8 +25,10 @@ define(function(require) { */ app.config = { cloudUrl: cloudUrl || 'https://keys.whiteout.io', - symKeySize: 128, - symIvSize: 128, + privkeyServerUrl: 'https://keychain-test.whiteout.io', + serverPrivateKeyId: 'EE342F0DDBB0F3BE', + symKeySize: 256, + symIvSize: 96, asymKeySize: 2048, workerPath: 'js', gmail: { diff --git a/src/js/app-controller.js b/src/js/app-controller.js index b799ee4..15f5ef5 100644 --- a/src/js/app-controller.js +++ b/src/js/app-controller.js @@ -12,6 +12,7 @@ define(function(require) { OutboxBO = require('js/bo/outbox'), mailreader = require('mailreader'), ImapClient = require('imap-client'), + Crypto = require('js/crypto/crypto'), RestDAO = require('js/dao/rest-dao'), EmailDAO = require('js/dao/email-dao'), appConfig = require('js/app-config'), @@ -20,6 +21,7 @@ define(function(require) { KeychainDAO = require('js/dao/keychain-dao'), PublicKeyDAO = require('js/dao/publickey-dao'), LawnchairDAO = require('js/dao/lawnchair-dao'), + PrivateKeyDAO = require('js/dao/privatekey-dao'), InvitationDAO = require('js/dao/invitation-dao'), DeviceStorageDAO = require('js/dao/devicestorage-dao'), UpdateHandler = require('js/util/update/update-handler'); @@ -55,7 +57,7 @@ define(function(require) { }; self.buildModules = function(options) { - var lawnchairDao, restDao, pubkeyDao, emailDao, keychain, pgp, userStorage, pgpbuilder, oauth, appConfigStore; + var lawnchairDao, restDao, pubkeyDao, privkeyDao, crypto, emailDao, keychain, pgp, userStorage, pgpbuilder, oauth, appConfigStore; // start the mailreader's worker thread mailreader.startWorker(config.workerPath + '/../lib/mailreader-parser-worker.js'); @@ -64,9 +66,12 @@ define(function(require) { restDao = new RestDAO(); lawnchairDao = new LawnchairDAO(); pubkeyDao = new PublicKeyDAO(restDao); + privkeyDao = new PrivateKeyDAO(new RestDAO(config.privkeyServerUrl)); oauth = new OAuth(new RestDAO('https://www.googleapis.com')); - self._keychain = keychain = new KeychainDAO(lawnchairDao, pubkeyDao); + crypto = new Crypto(); + self._pgp = pgp = new PGP(); + self._keychain = keychain = new KeychainDAO(lawnchairDao, pubkeyDao, privkeyDao, crypto, pgp); keychain.requestPermissionForKeyUpdate = function(params, callback) { var message = params.newKey ? str.updatePublicKeyMsgNewKey : str.updatePublicKeyMsgRemovedKey; message = message.replace('{0}', params.userId); @@ -85,7 +90,6 @@ define(function(require) { self._auth = new Auth(appConfigStore, oauth, new RestDAO('/ca')); self._userStorage = userStorage = new DeviceStorageDAO(lawnchairDao); self._invitationDao = new InvitationDAO(restDao); - self._crypto = pgp = new PGP(); self._pgpbuilder = pgpbuilder = new PgpBuilder(); self._emailDao = emailDao = new EmailDAO(keychain, pgp, userStorage, pgpbuilder, mailreader); self._outboxBo = new OutboxBO(emailDao, keychain, userStorage); diff --git a/src/js/app.js b/src/js/app.js index 5f92e05..37a70ed 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -8,17 +8,19 @@ requirejs([ 'js/controller/add-account', 'js/controller/account', 'js/controller/set-passphrase', + 'js/controller/privatekey-upload', 'js/controller/contacts', 'js/controller/about', 'js/controller/login', 'js/controller/login-initial', 'js/controller/login-new-device', 'js/controller/login-existing', + 'js/controller/login-privatekey-download', 'js/controller/mail-list', 'js/controller/read', 'js/controller/write', 'js/controller/navigation', - 'cryptoLib/util', + 'js/crypto/util', 'js/util/error', 'fastclick', 'angularSanitize', @@ -31,12 +33,14 @@ requirejs([ AddAccountCtrl, AccountCtrl, SetPassphraseCtrl, + PrivateKeyUploadCtrl, ContactsCtrl, AboutCtrl, LoginCtrl, LoginInitialCtrl, LoginNewDeviceCtrl, LoginExistingCtrl, + LoginPrivateKeyDownloadCtrl, MailListCtrl, ReadCtrl, WriteCtrl, @@ -89,6 +93,10 @@ requirejs([ templateUrl: 'tpl/login-new-device.html', controller: LoginNewDeviceCtrl }); + $routeProvider.when('/login-privatekey-download', { + templateUrl: 'tpl/login-privatekey-download.html', + controller: LoginPrivateKeyDownloadCtrl + }); $routeProvider.when('/desktop', { templateUrl: 'tpl/desktop.html', controller: NavigationCtrl @@ -113,6 +121,7 @@ requirejs([ app.controller('MailListCtrl', MailListCtrl); app.controller('AccountCtrl', AccountCtrl); app.controller('SetPassphraseCtrl', SetPassphraseCtrl); + app.controller('PrivateKeyUploadCtrl', PrivateKeyUploadCtrl); app.controller('ContactsCtrl', ContactsCtrl); app.controller('AboutCtrl', AboutCtrl); app.controller('DialogCtrl', DialogCtrl); diff --git a/src/js/bo/outbox.js b/src/js/bo/outbox.js index a9dd582..8a09cfb 100644 --- a/src/js/bo/outbox.js +++ b/src/js/bo/outbox.js @@ -2,7 +2,7 @@ define(function(require) { 'use strict'; var _ = require('underscore'), - util = require('cryptoLib/util'), + util = require('js/crypto/util'), config = require('js/app-config').config, outboxDb = 'email_OUTBOX'; @@ -27,7 +27,7 @@ define(function(require) { this._outboxBusy = false; }; - /** + /** * This function activates the periodic checking of the local device storage for pending mails. * @param {Function} callback(error, pendingMailsCount) Callback that informs you about the count of pending mails. */ diff --git a/src/js/controller/account.js b/src/js/controller/account.js index 3eceaaf..a811175 100644 --- a/src/js/controller/account.js +++ b/src/js/controller/account.js @@ -12,7 +12,7 @@ define(function(require) { var AccountCtrl = function($scope) { userId = appController._emailDao._account.emailAddress; keychain = appController._keychain; - pgp = appController._crypto; + pgp = appController._pgp; $scope.state.account = { toggle: function(to) { diff --git a/src/js/controller/contacts.js b/src/js/controller/contacts.js index 9fb6791..f66f01e 100644 --- a/src/js/controller/contacts.js +++ b/src/js/controller/contacts.js @@ -12,7 +12,7 @@ define(function(require) { var ContactsCtrl = function($scope) { keychain = appController._keychain, - pgp = appController._crypto; + pgp = appController._pgp; $scope.state.contacts = { toggle: function(to) { diff --git a/src/js/controller/login-new-device.js b/src/js/controller/login-new-device.js index 3918ff8..bac997a 100644 --- a/src/js/controller/login-new-device.js +++ b/src/js/controller/login-new-device.js @@ -6,7 +6,7 @@ define(function(require) { var LoginExistingCtrl = function($scope, $location) { var emailDao = appController._emailDao, - pgp = appController._crypto; + pgp = appController._pgp; $scope.incorrect = false; diff --git a/src/js/controller/login-privatekey-download.js b/src/js/controller/login-privatekey-download.js new file mode 100644 index 0000000..4ea5532 --- /dev/null +++ b/src/js/controller/login-privatekey-download.js @@ -0,0 +1,103 @@ +define(function(require) { + 'use strict'; + + var appController = require('js/app-controller'); + + var LoginPrivateKeyDownloadCtrl = function($scope, $location) { + var keychain = appController._keychain, + emailDao = appController._emailDao, + userId = emailDao._account.emailAddress; + + $scope.step = 1; + + $scope.verifyRecoveryToken = function(callback) { + if (!$scope.recoveryToken) { + $scope.onError(new Error('Please set the recovery token!')); + return; + } + + keychain.getUserKeyPair(userId, function(err, keypair) { + if (err) { + $scope.onError(err); + return; + } + + // remember for storage later + $scope.cachedKeypair = keypair; + + keychain.downloadPrivateKey({ + userId: userId, + keyId: keypair.publicKey._id, + recoveryToken: $scope.recoveryToken + }, function(err, encryptedPrivateKey) { + if (err) { + $scope.onError(err); + return; + } + + $scope.encryptedPrivateKey = encryptedPrivateKey; + callback(); + }); + }); + }; + + $scope.decryptAndStorePrivateKeyLocally = function() { + var inputCode = '' + $scope.code0 + $scope.code1 + $scope.code2 + $scope.code3 + $scope.code4 + $scope.code5; + + if (!inputCode) { + $scope.onError(new Error('Please enter the keychain code!')); + return; + } + + var options = $scope.encryptedPrivateKey; + options.code = inputCode.toUpperCase(); + + keychain.decryptAndStorePrivateKeyLocally(options, function(err, privateKey) { + if (err) { + $scope.onError(err); + return; + } + + // add private key to cached keypair object + $scope.cachedKeypair.privateKey = privateKey; + + // try empty passphrase + emailDao.unlock({ + keypair: $scope.cachedKeypair, + passphrase: undefined + }, function(err) { + if (err) { + // go to passphrase login screen + $scope.goTo('/login-existing'); + return; + } + + // passphrase is corrent ... go to main app + $scope.goTo('/desktop'); + }); + }); + }; + + $scope.goForward = function() { + if ($scope.step === 1) { + $scope.verifyRecoveryToken(function() { + $scope.step++; + $scope.$apply(); + }); + return; + } + + if ($scope.step === 2) { + $scope.decryptAndStorePrivateKeyLocally(); + return; + } + }; + + $scope.goTo = function(location) { + $location.path(location); + $scope.$apply(); + }; + }; + + return LoginPrivateKeyDownloadCtrl; +}); \ No newline at end of file diff --git a/src/js/controller/login.js b/src/js/controller/login.js index ac96b47..37c7caf 100644 --- a/src/js/controller/login.js +++ b/src/js/controller/login.js @@ -52,9 +52,28 @@ define(function(require) { if (typeof availableKeys === 'undefined') { // no public key available, start onboarding process goTo('/login-initial'); - } else if (!availableKeys.privateKey) { - // no private key, import key - goTo('/login-new-device'); + + } else if (availableKeys && !availableKeys.privateKey) { + // check if private key is synced + appController._keychain.requestPrivateKeyDownload({ + userId: availableKeys.publicKey.userId, + keyId: availableKeys.publicKey._id, + }, function(err, privateKeySynced) { + if (err) { + $scope.onError(err); + return; + } + + if (privateKeySynced) { + // private key is synced, proceed to download + goTo('/login-privatekey-download'); + return; + } + + // no private key, import key file + goTo('/login-new-device'); + }); + } else { // public and private key available, try empty passphrase appController._emailDao.unlock({ diff --git a/src/js/controller/privatekey-upload.js b/src/js/controller/privatekey-upload.js new file mode 100644 index 0000000..020a578 --- /dev/null +++ b/src/js/controller/privatekey-upload.js @@ -0,0 +1,170 @@ +define(function(require) { + 'use strict'; + + var appController = require('js/app-controller'), + keychain, pgp; + + var PrivateKeyUploadCtrl = function($scope) { + keychain = appController._keychain; + pgp = keychain._pgp; + + $scope.state.privateKeyUpload = { + toggle: function(to) { + // open lightbox + $scope.state.lightbox = (to) ? 'privatekey-upload' : undefined; + if (!to) { + return; + } + + // show syncing status + $scope.step = 4; + // check if key is already synced + $scope.checkServerForKey(function(privateKeySynced) { + if (privateKeySynced) { + // close lightbox + $scope.state.lightbox = undefined; + // show message + $scope.onError({ + title: 'Info', + message: 'Your PGP key has already been synced.' + }); + return; + } + + // show sync ui if key is not synced + $scope.displayUploadUi(); + }); + } + }; + + $scope.checkServerForKey = function(callback) { + var keyParams = pgp.getKeyParams(); + keychain.requestPrivateKeyDownload({ + userId: keyParams.userId, + keyId: keyParams._id, + }, function(err, privateKeySynced) { + if (err) { + $scope.onError(err); + return; + } + + if (privateKeySynced) { + callback(privateKeySynced); + return; + } + + callback(); + }); + }; + + $scope.displayUploadUi = function() { + // go to step 1 + $scope.step = 1; + // generate new code for the user + $scope.code = $scope.generateCode(); + $scope.displayedCode = $scope.code.slice(0, 4) + '-' + $scope.code.slice(4, 8) + '-' + $scope.code.slice(8, 12) + '-' + $scope.code.slice(12, 16) + '-' + $scope.code.slice(16, 20) + '-' + $scope.code.slice(20, 24); + }; + + $scope.generateCode = function() { + function randomString(length, chars) { + var result = ''; + var randomValues = new Uint8Array(length); // get random length number of bytes + window.crypto.getRandomValues(randomValues); + for (var i = 0; i < length; i++) { + result += chars[Math.round(randomValues[i] / 255 * (chars.length - 1))]; + } + return result; + } + return randomString(24, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + }; + + $scope.verifyCode = function() { + var inputCode = '' + $scope.code0 + $scope.code1 + $scope.code2 + $scope.code3 + $scope.code4 + $scope.code5; + + if (inputCode.toUpperCase() !== $scope.code) { + var err = new Error('The code does not match. Please go back and check the generated code.'); + err.sync = true; + $scope.onError(err); + return false; + } + + return true; + }; + + $scope.setDeviceName = function(callback) { + keychain.setDeviceName($scope.deviceName, callback); + }; + + $scope.encryptAndUploadKey = function(callback) { + var userId = appController._emailDao._account.emailAddress; + var code = $scope.code; + + // register device to keychain service + keychain.registerDevice({ + userId: userId + }, function(err) { + if (err) { + $scope.onError(err); + return; + } + + // encrypt private PGP key using code and upload + keychain.uploadPrivateKey({ + userId: userId, + code: code + }, callback); + }); + }; + + $scope.goBack = function() { + if ($scope.step > 1) { + $scope.step--; + } + }; + + $scope.goForward = function() { + if ($scope.step < 2) { + $scope.step++; + return; + } + + if ($scope.step === 2 && $scope.verifyCode()) { + $scope.step++; + return; + } + + if ($scope.step === 3) { + // set device name to local storage + $scope.setDeviceName(function(err) { + if (err) { + $scope.onError(err); + return; + } + + // show spinner + $scope.step++; + $scope.$apply(); + + // init key sync + $scope.encryptAndUploadKey(function(err) { + if (err) { + $scope.onError(err); + return; + } + + // close sync dialog + $scope.state.privateKeyUpload.toggle(false); + // show success message + $scope.onError({ + title: 'Success', + message: 'Whiteout Keychain setup successful!' + }); + }); + }); + } + }; + + }; + + return PrivateKeyUploadCtrl; +}); \ No newline at end of file diff --git a/src/js/controller/read.js b/src/js/controller/read.js index ef346ef..703104e 100644 --- a/src/js/controller/read.js +++ b/src/js/controller/read.js @@ -5,7 +5,7 @@ define(function(require) { download = require('js/util/download'), angular = require('angular'), str = require('js/app-config').string, - emailDao, invitationDao, outbox, crypto, keychain; + emailDao, invitationDao, outbox, pgp, keychain; // // Controller @@ -16,7 +16,7 @@ define(function(require) { emailDao = appController._emailDao; invitationDao = appController._invitationDao; outbox = appController._outboxBo; - crypto = appController._crypto; + pgp = appController._pgp; keychain = appController._keychain; // set default value so that the popover height is correct on init @@ -47,7 +47,7 @@ define(function(require) { return; } - var fpr = crypto.getFingerprint(pubkey.publicKey); + var fpr = pgp.getFingerprint(pubkey.publicKey); var formatted = fpr.slice(32); $scope.keyId = 'PGP key: ' + formatted; diff --git a/src/js/controller/set-passphrase.js b/src/js/controller/set-passphrase.js index 811a55b..13fc7ad 100644 --- a/src/js/controller/set-passphrase.js +++ b/src/js/controller/set-passphrase.js @@ -10,7 +10,7 @@ define(function(require) { var SetPassphraseCtrl = function($scope) { keychain = appController._keychain; - pgp = appController._crypto; + pgp = appController._pgp; $scope.state.setPassphrase = { toggle: function(to) { diff --git a/src/js/controller/write.js b/src/js/controller/write.js index d1c6593..4b84054 100644 --- a/src/js/controller/write.js +++ b/src/js/controller/write.js @@ -4,17 +4,17 @@ define(function(require) { var angular = require('angular'), _ = require('underscore'), appController = require('js/app-controller'), - aes = require('cryptoLib/aes-cbc'), - util = require('cryptoLib/util'), + aes = require('js/crypto/aes-gcm'), + util = require('js/crypto/util'), str = require('js/app-config').string, - crypto, emailDao, outbox, keychainDao; + pgp, emailDao, outbox, keychainDao; // // Controller // var WriteCtrl = function($scope, $filter) { - crypto = appController._crypto; + pgp = appController._pgp; emailDao = appController._emailDao, outbox = appController._outboxBo; keychainDao = appController._keychain; @@ -218,7 +218,7 @@ define(function(require) { return; } - var fpr = crypto.getFingerprint(recipient.key.publicKey); + var fpr = pgp.getFingerprint(recipient.key.publicKey); var formatted = fpr.slice(32); $scope.keyId = formatted; diff --git a/src/js/crypto/crypto-batch-worker.js b/src/js/crypto/crypto-batch-worker.js deleted file mode 100644 index 59aaa63..0000000 --- a/src/js/crypto/crypto-batch-worker.js +++ /dev/null @@ -1,93 +0,0 @@ -(function() { - 'use strict'; - - // import web worker dependencies - importScripts('../../lib/require.js'); - - /** - * In the web worker thread context, 'this' and 'self' can be used as a global - * variable namespace similar to the 'window' object in the main thread - */ - self.onmessage = function(e) { - // fetch dependencies via require.js - require(['../../require-config'], function() { - require.config({ - baseUrl: '../../lib' - }); - - require(['cryptoLib/crypto-batch'], function(batch) { - - var output; - - try { - output = doOperation(batch, e.data); - } catch (e) { - output = { - err: { - errMsg: (e.message) ? e.message : e - } - }; - } - - // pass output back to main thread - self.postMessage(output); - - }); - }); - }; - - function doOperation(batch, i) { - var output; - - // - // Asymmetric encryption - // - - if (i.type === 'asymEncrypt' && i.receiverPubkeys && i.senderPrivkey && i.list) { - // start encryption - output = batch.encryptListForUser(i.list, i.receiverPubkeys, i.senderPrivkey); - - } else if (i.type === 'asymDecrypt' && i.senderPubkeys && i.receiverPrivkey && i.list) { - // start decryption - output = batch.decryptListForUser(i.list, i.senderPubkeys, i.receiverPrivkey); - } - - // - // Symmetric encryption - // - else if (i.type === 'symEncrypt' && i.list) { - // start encryption - output = batch.authEncryptList(i.list); - - } else if (i.type === 'symDecrypt' && i.list && i.keys) { - // start decryption - output = batch.authDecryptList(i.list, i.keys); - } - - // - // Reencryption of asymmetric items to symmetric items - // - else if (i.type === 'reencrypt' && i.senderPubkeys && i.receiverPrivkey && i.list && i.symKey) { - // start validation and re-encryption - output = batch.reencryptListKeysForUser(i.list, i.senderPubkeys, i.receiverPrivkey, i.symKey); - - } else if (i.type === 'decryptItems' && i.symKey && i.list) { - // start decryption - output = batch.decryptKeysAndList(i.list, i.symKey); - } - - // - // Error - // - else { - output = { - err: { - errMsg: 'Not all arguments for web worker crypto are defined!' - } - }; - } - - return output; - } - -}()); \ No newline at end of file diff --git a/src/js/crypto/crypto.js b/src/js/crypto/crypto.js index 95ec3ee..7150966 100644 --- a/src/js/crypto/crypto.js +++ b/src/js/crypto/crypto.js @@ -5,120 +5,54 @@ define(function(require) { 'use strict'; - var util = require('cryptoLib/util'), - aes = require('cryptoLib/aes-cbc'), - rsa = require('cryptoLib/rsa'), - cryptoBatch = require('cryptoLib/crypto-batch'), + var aes = require('js/crypto/aes-gcm'), pbkdf2 = require('js/crypto/pbkdf2'), config = require('js/app-config').config; - var passBasedKey, - BATCH_WORKER = '/crypto/crypto-batch-worker.js', - PBKDF2_WORKER = '/crypto/pbkdf2-worker.js'; + var PBKDF2_WORKER = '/crypto/pbkdf2-worker.js'; - var Crypto = function() { - - }; + var Crypto = function() {}; /** - * Initializes the crypto modules by fetching the user's - * encrypted secret key from storage and storing it in memory. + * Encrypt plaintext using AES-GCM. + * @param {String} plaintext The input string in UTF-16 + * @param {String} key The base64 encoded key + * @param {String} iv The base64 encoded IV + * @param {Function} callback(error, ciphertext) + * @return {String} The base64 encoded ciphertext */ - Crypto.prototype.init = function(args, callback) { - var self = this; + Crypto.prototype.encrypt = function(plaintext, key, iv, callback) { + var ct; - // valdiate input - if (!args.emailAddress || !args.keySize || !args.rsaKeySize || typeof args.password !== 'string' || !args.salt) { - callback({ - errMsg: 'Crypto init failed. Not all args set!' - }); + try { + ct = aes.encrypt(plaintext, key, iv); + } catch (err) { + callback(err); return; } - self.emailAddress = args.emailAddress; - self.keySize = args.keySize; - self.ivSize = args.keySize; - self.rsaKeySize = args.rsaKeySize; + callback(null, ct); + }; - // derive PBKDF2 from password in web worker thread - self.deriveKey(args.password, args.salt, self.keySize, function(err, derivedKey) { - if (err) { - callback(err); - return; - } + /** + * Decrypt ciphertext suing AES-GCM + * @param {String} ciphertext The base64 encoded ciphertext + * @param {String} key The base64 encoded key + * @param {String} iv The base64 encoded IV + * @param {Function} callback(error, plaintext) + * @return {String} The decrypted plaintext in UTF-16 + */ + Crypto.prototype.decrypt = function(ciphertext, key, iv, callback) { + var pt; - // remember pbkdf2 for later use - passBasedKey = derivedKey; - - // check if key exists - if (!args.storedKeypair) { - // generate keys, encrypt and persist if none exists - generateKeypair(derivedKey); - } else { - // decrypt key - decryptKeypair(args.storedKeypair, derivedKey); - } - - }); - - function generateKeypair(derivedKey) { - // generate RSA keypair in web worker - rsa.generateKeypair(self.rsaKeySize, function(err, generatedKeypair) { - if (err) { - callback(err); - return; - } - - // encrypt keypair - var iv = util.random(self.ivSize); - var encryptedPrivateKey = aes.encrypt(generatedKeypair.privkeyPem, derivedKey, iv); - - // new encrypted keypair object - var newKeypair = { - publicKey: { - _id: generatedKeypair._id, - userId: self.emailAddress, - publicKey: generatedKeypair.pubkeyPem - }, - privateKey: { - _id: generatedKeypair._id, - userId: self.emailAddress, - encryptedKey: encryptedPrivateKey, - iv: iv - } - }; - - // return generated keypair for storage in keychain dao - callback(null, newKeypair); - }); + try { + pt = aes.decrypt(ciphertext, key, iv); + } catch (err) { + callback(err); + return; } - function decryptKeypair(storedKeypair, derivedKey) { - var decryptedPrivateKey; - - // validate input - if (!storedKeypair || !storedKeypair.privateKey || !storedKeypair.privateKey.encryptedKey || !storedKeypair.privateKey.iv) { - callback({ - errMsg: 'Incomplete arguments for private key decryption!' - }); - return; - } - - // try to decrypt with derivedKey - try { - var prK = storedKeypair.privateKey; - decryptedPrivateKey = aes.decrypt(prK.encryptedKey, derivedKey, prK.iv); - } catch (ex) { - callback({ - errMsg: 'Wrong password!' - }); - return; - } - // set rsa keys - rsa.init(storedKeypair.publicKey.publicKey, decryptedPrivateKey, storedKeypair.publicKey._id); - - callback(); - } + callback(null, pt); }; /** @@ -139,181 +73,6 @@ define(function(require) { }); }; - // - // En/Decrypt a list of items with AES in a WebWorker thread - // - - Crypto.prototype.symEncryptList = function(list, callback) { - var self = this, - key, envelope, envelopes = []; - - // generate single secret key shared for all list items - key = util.random(self.keySize); - - // package objects into batchable envelope format - list.forEach(function(i) { - envelope = { - id: i.id, - plaintext: i, - key: key, - iv: util.random(self.ivSize) - }; - envelopes.push(envelope); - }); - - startWorker({ - script: BATCH_WORKER, - args: { - type: 'symEncrypt', - list: envelopes - }, - callback: function(err, encryptedList) { - // return generated secret key - callback(err, { - key: key, - list: encryptedList - }); - }, - noWorker: function() { - return cryptoBatch.authEncryptList(envelopes); - } - }); - }; - - Crypto.prototype.symDecryptList = function(list, keys, callback) { - startWorker({ - script: BATCH_WORKER, - args: { - type: 'symDecrypt', - list: list, - keys: keys - }, - callback: callback, - noWorker: function() { - return cryptoBatch.authDecryptList(list, keys); - } - }); - }; - - // - // En/Decrypt something speficially using the user's secret key - // - - Crypto.prototype.encryptListForUser = function(list, receiverPubkeys, callback) { - var self = this, - envelope, envelopes = []; - - if (!receiverPubkeys || receiverPubkeys.length !== 1) { - callback({ - errMsg: 'Encryption is currently implemented for only one receiver!' - }); - return; - } - - var keypair = rsa.exportKeys(); - var senderPrivkey = { - _id: keypair._id, - privateKey: keypair.privkeyPem - }; - - // package objects into batchable envelope format - list.forEach(function(i) { - envelope = { - id: i.id, - plaintext: i, - key: util.random(self.keySize), - iv: util.random(self.ivSize), - receiverPk: receiverPubkeys[0]._id - }; - envelopes.push(envelope); - }); - - startWorker({ - script: BATCH_WORKER, - args: { - type: 'asymEncrypt', - list: envelopes, - senderPrivkey: senderPrivkey, - receiverPubkeys: receiverPubkeys - }, - callback: callback, - noWorker: function() { - return cryptoBatch.encryptListForUser(envelopes, receiverPubkeys, senderPrivkey); - } - }); - }; - - Crypto.prototype.decryptListForUser = function(list, senderPubkeys, callback) { - if (!senderPubkeys || senderPubkeys < 1) { - callback({ - errMsg: 'Sender public keys must be set!' - }); - return; - } - - var keypair = rsa.exportKeys(); - var receiverPrivkey = { - _id: keypair._id, - privateKey: keypair.privkeyPem - }; - - startWorker({ - script: BATCH_WORKER, - args: { - type: 'asymDecrypt', - list: list, - receiverPrivkey: receiverPrivkey, - senderPubkeys: senderPubkeys - }, - callback: callback, - noWorker: function() { - return cryptoBatch.decryptListForUser(list, senderPubkeys, receiverPrivkey); - } - }); - }; - - // - // Re-encrypt keys item and items seperately - // - - Crypto.prototype.reencryptListKeysForUser = function(list, senderPubkeys, callback) { - var keypair = rsa.exportKeys(); - var receiverPrivkey = { - _id: keypair._id, - privateKey: keypair.privkeyPem - }; - - startWorker({ - script: BATCH_WORKER, - args: { - type: 'reencrypt', - list: list, - receiverPrivkey: receiverPrivkey, - senderPubkeys: senderPubkeys, - symKey: passBasedKey - }, - callback: callback, - noWorker: function() { - return cryptoBatch.reencryptListKeysForUser(list, senderPubkeys, receiverPrivkey, passBasedKey); - } - }); - }; - - Crypto.prototype.decryptKeysAndList = function(list, callback) { - startWorker({ - script: BATCH_WORKER, - args: { - type: 'decryptItems', - list: list, - symKey: passBasedKey - }, - callback: callback, - noWorker: function() { - return cryptoBatch.decryptKeysAndList(list, passBasedKey); - } - }); - }; - // // helper functions // diff --git a/src/js/crypto/pbkdf2.js b/src/js/crypto/pbkdf2.js index ec01b69..3a0b12a 100644 --- a/src/js/crypto/pbkdf2.js +++ b/src/js/crypto/pbkdf2.js @@ -1,24 +1,25 @@ /** * A Wrapper for Forge's PBKDF2 function */ -define(['node-forge'], function(forge) { +define(['forge'], function(forge) { 'use strict'; var self = {}; /** - * PBKDF2-HMAC-SHA1 key derivation with a random salt and 1000 iterations - * @param password [String] The password in UTF8 - * @param salt [String] The base64 encoded salt - * @param keySize [Number] The key size in bits - * @return [String] The base64 encoded key + * PBKDF2-HMAC-SHA256 key derivation with a random salt and 10000 iterations + * @param {String} password The password in UTF8 + * @param {String} salt The base64 encoded salt + * @param {String} keySize The key size in bits + * @return {String} The base64 encoded key */ self.getKey = function(password, salt, keySize) { - var key = forge.pkcs5.pbkdf2(password, forge.util.decode64(salt), 1000, keySize / 8); - var keyBase64 = forge.util.encode64(key); + var saltUtf8 = forge.util.decode64(salt); + var md = forge.md.sha256.create(); + var key = forge.pkcs5.pbkdf2(password, saltUtf8, 10000, keySize / 8, md); - return keyBase64; + return forge.util.encode64(key); }; return self; -}); +}); \ No newline at end of file diff --git a/src/js/crypto/pgp.js b/src/js/crypto/pgp.js index e7e1331..2719925 100644 --- a/src/js/crypto/pgp.js +++ b/src/js/crypto/pgp.js @@ -20,23 +20,23 @@ define(function(require) { var userId, passphrase; if (!util.emailRegEx.test(options.emailAddress) || !options.keySize) { - callback({ - errMsg: 'Crypto init failed. Not all options set!' - }); + callback(new Error('Crypto init failed. Not all options set!')); return; } - // generate keypair (keytype 1=RSA) + // generate keypair userId = 'Whiteout User <' + options.emailAddress + '>'; passphrase = (options.passphrase) ? options.passphrase : undefined; - openpgp.generateKeyPair(1, options.keySize, userId, passphrase, onGenerated); + openpgp.generateKeyPair({ + keyType: 1, // (keytype 1=RSA) + numBits: options.keySize, + userId: userId, + passphrase: passphrase + }, onGenerated); function onGenerated(err, keys) { if (err) { - callback({ - errMsg: 'Keygeneration failed!', - err: err - }); + callback(new Error('Keygeneration failed!')); return; } @@ -141,9 +141,7 @@ define(function(require) { // check options if (!options.privateKeyArmored || !options.publicKeyArmored) { - callback({ - errMsg: 'Importing keys failed. Not all options set!' - }); + callback(new Error('Importing keys failed. Not all options set!')); return; } @@ -158,18 +156,14 @@ define(function(require) { this._privateKey = openpgp.key.readArmored(options.privateKeyArmored).keys[0]; } catch (e) { resetKeys(); - callback({ - errMsg: 'Importing keys failed. Parsing error!' - }); + callback(new Error('Importing keys failed. Parsing error!')); return; } // decrypt private key with passphrase if (!this._privateKey.decrypt(options.passphrase)) { resetKeys(); - callback({ - errMsg: 'Incorrect passphrase!' - }); + callback(new Error('Incorrect passphrase!')); return; } @@ -178,9 +172,7 @@ define(function(require) { privKeyId = this._privateKey.getKeyPacket().getKeyId().toHex(); if (!pubKeyId || !privKeyId || pubKeyId !== privKeyId) { resetKeys(); - callback({ - errMsg: 'Key IDs dont match!' - }); + callback(new Error('Key IDs dont match!')); return; } @@ -192,9 +184,7 @@ define(function(require) { */ PGP.prototype.exportKeys = function(callback) { if (!this._publicKey || !this._privateKey) { - callback({ - errMsg: 'Could not export keys!' - }); + callback(new Error('Could not export keys!')); return; } @@ -215,9 +205,7 @@ define(function(require) { newPassphrase = (options.newPassphrase) ? options.newPassphrase : undefined; if (!options.privateKeyArmored) { - callback({ - errMsg: 'Private key must be specified to change passphrase!' - }); + callback(new Error('Private key must be specified to change passphrase!')); return; } @@ -231,17 +219,13 @@ define(function(require) { try { privKey = openpgp.key.readArmored(options.privateKeyArmored).keys[0]; } catch (e) { - callback({ - errMsg: 'Importing key failed. Parsing error!' - }); + callback(new Error('Importing key failed. Parsing error!')); return; } // decrypt private key with passphrase if (!privKey.decrypt(options.oldPassphrase)) { - callback({ - errMsg: 'Old passphrase incorrect!' - }); + callback(new Error('Old passphrase incorrect!')); return; } @@ -253,17 +237,13 @@ define(function(require) { } newKeyArmored = privKey.armor(); } catch (e) { - callback({ - errMsg: 'Setting new passphrase failed!' - }); + callback(new Error('Setting new passphrase failed!')); return; } // check if new passphrase really works if (!privKey.decrypt(newPassphrase)) { - callback({ - errMsg: 'Decrypting key with new passphrase failed!' - }); + callback(new Error('Decrypting key with new passphrase failed!')); return; } @@ -278,9 +258,7 @@ define(function(require) { // check keys if (!this._privateKey || publicKeysArmored.length < 1) { - callback({ - errMsg: 'Error encrypting. Keys must be set!' - }); + callback(new Error('Error encrypting. Keys must be set!')); return; } @@ -290,10 +268,7 @@ define(function(require) { publicKeys = publicKeys.concat(openpgp.key.readArmored(pubkeyArmored).keys); }); } catch (err) { - callback({ - errMsg: 'Error encrypting plaintext!', - err: err - }); + callback(new Error('Error encrypting plaintext!')); return; } @@ -309,9 +284,7 @@ define(function(require) { // check keys if (!this._privateKey || !publicKeyArmored) { - callback({ - errMsg: 'Error decrypting. Keys must be set!' - }); + callback(new Error('Error decrypting. Keys must be set!')); return; } @@ -320,10 +293,7 @@ define(function(require) { publicKeys = openpgp.key.readArmored(publicKeyArmored).keys; message = openpgp.message.readArmored(ciphertext); } catch (err) { - callback({ - errMsg: 'Error decrypting PGP message!', - err: err - }); + callback(new Error('Error decrypting PGP message!')); return; } @@ -332,10 +302,7 @@ define(function(require) { function onDecrypted(err, decrypted) { if (err) { - callback({ - errMsg: 'Error decrypting PGP message!', - err: err - }); + callback(new Error('Error decrypting PGP message!')); return; } @@ -347,9 +314,7 @@ define(function(require) { } }); if (!signaturesValid) { - callback({ - errMsg: 'Verifying PGP signature failed!' - }); + callback(new Error('Verifying PGP signature failed!')); return; } diff --git a/src/js/dao/email-dao.js b/src/js/dao/email-dao.js index 7614249..f44e393 100644 --- a/src/js/dao/email-dao.js +++ b/src/js/dao/email-dao.js @@ -1,7 +1,7 @@ define(function(require) { 'use strict'; - var util = require('cryptoLib/util'), + var util = require('js/crypto/util'), _ = require('underscore'), config = require('js/app-config').config, str = require('js/app-config').string; @@ -11,14 +11,14 @@ define(function(require) { * PGP de-/encryption, receiving via IMAP, sending via SMTP, MIME parsing, local db persistence * * @param {Object} keychain The keychain DAO handles keys transparently - * @param {Object} crypto Orchestrates decryption + * @param {Object} pgp Orchestrates decryption * @param {Object} devicestorage Handles persistence to the local indexed db * @param {Object} pgpbuilder Generates and encrypts MIME and SMTP messages * @param {Object} mailreader Parses MIME messages received from IMAP */ - var EmailDAO = function(keychain, crypto, devicestorage, pgpbuilder, mailreader) { + var EmailDAO = function(keychain, pgp, devicestorage, pgpbuilder, mailreader) { this._keychain = keychain; - this._crypto = crypto; + this._pgp = pgp; this._devicestorage = devicestorage; this._pgpbuilder = pgpbuilder; this._mailreader = mailreader; @@ -105,7 +105,7 @@ define(function(require) { } // no keypair for is stored for the user... generate a new one - self._crypto.generateKeys({ + self._pgp.generateKeys({ emailAddress: self._account.emailAddress, keySize: self._account.asymKeySize, passphrase: options.passphrase @@ -121,8 +121,8 @@ define(function(require) { function handleExistingKeypair(keypair) { var privKeyParams, pubKeyParams; try { - privKeyParams = self._crypto.getKeyParams(keypair.privateKey.encryptedKey); - pubKeyParams = self._crypto.getKeyParams(keypair.publicKey.publicKey); + privKeyParams = self._pgp.getKeyParams(keypair.privateKey.encryptedKey); + pubKeyParams = self._pgp.getKeyParams(keypair.publicKey.publicKey); } catch (e) { callback(new Error('Error reading key params!')); return; @@ -148,7 +148,7 @@ define(function(require) { } // import existing key pair into crypto module - self._crypto.importKeys({ + self._pgp.importKeys({ passphrase: options.passphrase, privateKeyArmored: keypair.privateKey.encryptedKey, publicKeyArmored: keypair.publicKey.publicKey @@ -159,14 +159,14 @@ define(function(require) { } // set decrypted privateKey to pgpMailer - self._pgpbuilder._privateKey = self._crypto._privateKey; + self._pgpbuilder._privateKey = self._pgp._privateKey; callback(); }); } function handleGenerated(generatedKeypair) { // import the new key pair into crypto module - self._crypto.importKeys({ + self._pgp.importKeys({ passphrase: options.passphrase, privateKeyArmored: generatedKeypair.privateKeyArmored, publicKeyArmored: generatedKeypair.publicKeyArmored @@ -196,7 +196,7 @@ define(function(require) { } // set decrypted privateKey to pgpMailer - self._pgpbuilder._privateKey = self._crypto._privateKey; + self._pgpbuilder._privateKey = self._pgp._privateKey; callback(); }); }); @@ -818,7 +818,7 @@ define(function(require) { // get the receiver's public key to check the message signature var encryptedNode = filterBodyParts(message.bodyParts, 'encrypted')[0]; - self._crypto.decrypt(encryptedNode.content, senderPublicKey.publicKey, function(err, decrypted) { + self._pgp.decrypt(encryptedNode.content, senderPublicKey.publicKey, function(err, decrypted) { if (err || !decrypted) { showError(err.errMsg || err.message || 'An error occurred during the decryption.'); return; diff --git a/src/js/dao/keychain-dao.js b/src/js/dao/keychain-dao.js index d649012..a9099c1 100644 --- a/src/js/dao/keychain-dao.js +++ b/src/js/dao/keychain-dao.js @@ -5,13 +5,27 @@ define(function(require) { 'use strict'; - var _ = require('underscore'); + var _ = require('underscore'), + util = require('js/crypto/util'), + config = require('js/app-config').config; - var KeychainDAO = function(localDbDao, publicKeyDao) { + var DB_PUBLICKEY = 'publickey', + DB_PRIVATEKEY = 'privatekey', + DB_DEVICENAME = 'devicename', + DB_DEVICE_SECRET = 'devicesecret'; + + var KeychainDAO = function(localDbDao, publicKeyDao, privateKeyDao, crypto, pgp) { this._localDbDao = localDbDao; this._publicKeyDao = publicKeyDao; + this._privateKeyDao = privateKeyDao; + this._crypto = crypto; + this._pgp = pgp; }; + // + // Public key functions + // + /** * Verifies the public key of a user o nthe public key store * @param {String} uuid The uuid to verify the key @@ -170,7 +184,7 @@ define(function(require) { var self = this; // search local keyring for public key - self._localDbDao.list('publickey', 0, null, function(err, allPubkeys) { + self._localDbDao.list(DB_PUBLICKEY, 0, null, function(err, allPubkeys) { if (err) { callback(err); return; @@ -234,6 +248,492 @@ define(function(require) { } }; + // + // Device registration functions + // + + /** + * Set the device's memorable name e.g 'iPhone Work' + * @param {String} deviceName The device name + * @param {Function} callback(error) + */ + KeychainDAO.prototype.setDeviceName = function(deviceName, callback) { + if (!deviceName) { + callback(new Error('Please set a device name!')); + return; + } + + this._localDbDao.persist(DB_DEVICENAME, deviceName, callback); + }; + + /** + * Get the device' memorable name from local storage. Throws an error if not set + * @param {Function} callback(error, deviceName) + * @return {String} The device name + */ + KeychainDAO.prototype.getDeviceName = function(callback) { + // check if deviceName is already persisted in storage + this._localDbDao.read(DB_DEVICENAME, function(err, deviceName) { + if (err) { + callback(err); + return; + } + + if (!deviceName) { + callback(new Error('Device name not set!')); + return; + } + + callback(null, deviceName); + }); + }; + + /** + * Geneate a device specific key and secret to authenticate to the private key service. + * @param {Function} callback(error, deviceSecret:[base64 encoded string]) + */ + KeychainDAO.prototype.getDeviceSecret = function(callback) { + var self = this; + + // generate random deviceSecret or get from storage + self._localDbDao.read(DB_DEVICE_SECRET, function(err, storedDevSecret) { + if (err) { + callback(err); + return; + } + + if (storedDevSecret) { + // a device key is already available locally + callback(null, storedDevSecret); + return; + } + + // generate random deviceSecret + var deviceSecret = util.random(config.symKeySize); + // persist deviceSecret to local storage (in plaintext) + self._localDbDao.persist(DB_DEVICE_SECRET, deviceSecret, function(err) { + if (err) { + callback(err); + return; + } + + callback(null, deviceSecret); + }); + }); + }; + + /** + * Register the device on the private key server. This will give the device access to upload an encrypted private key. + * @param {String} options.userId The user's email address + * @param {Function} callback(error) + */ + KeychainDAO.prototype.registerDevice = function(options, callback) { + var self = this, + devName; + + // check if deviceName is already persisted in storage + self.getDeviceName(function(err, deviceName) { + if (err) { + callback(err); + return; + } + + requestDeviceRegistration(deviceName); + }); + + function requestDeviceRegistration(deviceName) { + devName = deviceName; + + // request device registration session key + self._privateKeyDao.requestDeviceRegistration({ + userId: options.userId, + deviceName: deviceName + }, function(err, regSessionKey) { + if (err) { + callback(err); + return; + } + + if (!regSessionKey.encryptedRegSessionKey) { + callback(new Error('Invalid format for session key!')); + return; + } + + decryptSessionKey(regSessionKey); + }); + } + + function decryptSessionKey(regSessionKey) { + self.lookupPublicKey(config.serverPrivateKeyId, function(err, serverPubkey) { + if (err) { + callback(err); + return; + } + + if (!serverPubkey || !serverPubkey.publicKey) { + callback(new Error('Server public key for device registration not found!')); + return; + } + + // decrypt the session key + var ct = regSessionKey.encryptedRegSessionKey; + self._pgp.decrypt(ct, serverPubkey.publicKey, function(err, decrypedSessionKey) { + if (err) { + callback(err); + return; + } + + uploadDeviceSecret(decrypedSessionKey); + }); + }); + } + + function uploadDeviceSecret(regSessionKey) { + // read device secret from local storage + self.getDeviceSecret(function(err, deviceSecret) { + if (err) { + callback(err); + return; + } + + // generate iv + var iv = util.random(config.symIvSize); + // encrypt deviceSecret + self._crypto.encrypt(deviceSecret, regSessionKey, iv, function(err, encryptedDeviceSecret) { + if (err) { + callback(err); + return; + } + + // upload encryptedDeviceSecret + self._privateKeyDao.uploadDeviceSecret({ + userId: options.userId, + deviceName: devName, + encryptedDeviceSecret: encryptedDeviceSecret, + iv: iv + }, callback); + }); + }); + } + }; + + // + // Private key functions + // + + /** + * Authenticate to the private key server (required before private PGP key upload). + * @param {String} userId The user's email address + * @param {Function} callback(error, authSessionKey) + * @return {Object} {sessionId:String, sessionKey:[base64 encoded]} + */ + KeychainDAO.prototype._authenticateToPrivateKeyServer = function(userId, callback) { + var self = this, + sessionId; + + // request auth session key required for upload + self._privateKeyDao.requestAuthSessionKey({ + userId: userId + }, function(err, authSessionKey) { + if (err) { + callback(err); + return; + } + + if (!authSessionKey.encryptedAuthSessionKey || !authSessionKey.encryptedChallenge || !authSessionKey.sessionId) { + callback(new Error('Invalid format for session key!')); + return; + } + + // remember session id for verification + sessionId = authSessionKey.sessionId; + + decryptSessionKey(authSessionKey); + }); + + function decryptSessionKey(authSessionKey) { + self.lookupPublicKey(config.serverPrivateKeyId, function(err, serverPubkey) { + if (err) { + callback(err); + return; + } + + if (!serverPubkey || !serverPubkey.publicKey) { + callback(new Error('Server public key for authentication not found!')); + return; + } + + // decrypt the session key + var ct1 = authSessionKey.encryptedAuthSessionKey; + self._pgp.decrypt(ct1, serverPubkey.publicKey, function(err, decryptedSessionKey) { + if (err) { + callback(err); + return; + } + + // decrypt the challenge + var ct2 = authSessionKey.encryptedChallenge; + self._pgp.decrypt(ct2, serverPubkey.publicKey, function(err, decryptedChallenge) { + if (err) { + callback(err); + return; + } + + encryptChallenge(decryptedSessionKey, decryptedChallenge); + }); + }); + }); + } + + function encryptChallenge(sessionKey, challenge) { + // get device secret + self.getDeviceSecret(function(err, deviceSecret) { + if (err) { + callback(err); + return; + } + + var iv = util.random(config.symIvSize); + // encrypt the challenge + self._crypto.encrypt(challenge, sessionKey, iv, function(err, encryptedChallenge) { + if (err) { + callback(err); + return; + } + + // encrypt the device secret + self._crypto.encrypt(deviceSecret, sessionKey, iv, function(err, encryptedDeviceSecret) { + if (err) { + callback(err); + return; + } + + replyChallenge({ + encryptedChallenge: encryptedChallenge, + encryptedDeviceSecret: encryptedDeviceSecret, + iv: iv + }, sessionKey); + }); + }); + }); + } + + function replyChallenge(response, sessionKey) { + // respond to challenge by uploading the with the session key encrypted challenge + self._privateKeyDao.verifyAuthentication({ + userId: userId, + sessionId: sessionId, + encryptedChallenge: response.encryptedChallenge, + encryptedDeviceSecret: response.encryptedDeviceSecret, + iv: response.iv + }, function(err) { + if (err) { + callback(err); + return; + } + + callback(null, { + sessionId: sessionId, + sessionKey: sessionKey + }); + }); + } + }; + + /** + * Encrypt and upload the private PGP key to the server. + * @param {String} options.userId The user's email address + * @param {String} options.code The randomly generated or self selected code used to derive the key for the encryption of the private PGP key + * @param {Function} callback(error) + */ + KeychainDAO.prototype.uploadPrivateKey = function(options, callback) { + var self = this, + keySize = config.symKeySize, + salt; + + if (!options.userId || !options.code) { + callback(new Error('Incomplete arguments!')); + return; + } + + deriveKey(options.code); + + function deriveKey(code) { + // generate random salt + salt = util.random(keySize); + // derive key from the code using PBKDF2 + self._crypto.deriveKey(code, salt, keySize, function(err, key) { + if (err) { + callback(err); + return; + } + + encryptPrivateKey(key); + }); + } + + function encryptPrivateKey(encryptionKey) { + // get private key from local storage + self.getUserKeyPair(options.userId, function(err, keypair) { + if (err) { + callback(err); + return; + } + + var privkeyId = keypair.privateKey._id, + pgpBlock = keypair.privateKey.encryptedKey; + + // encrypt the private key with the derived key + var iv = util.random(config.symIvSize); + self._crypto.encrypt(pgpBlock, encryptionKey, iv, function(err, ct) { + if (err) { + callback(err); + return; + } + + var payload = { + _id: privkeyId, + userId: options.userId, + encryptedPrivateKey: ct, + salt: salt, + iv: iv + }; + + uploadPrivateKey(payload); + }); + }); + } + + function uploadPrivateKey(payload) { + // authenticate to server for upload + self._authenticateToPrivateKeyServer(options.userId, function(err, authSessionKey) { + if (err) { + callback(err); + return; + } + + // encrypt encryptedPrivateKey again using authSessionKey + var pt = payload.encryptedPrivateKey, + iv = payload.iv, + key = authSessionKey.sessionKey; + self._crypto.encrypt(pt, key, iv, function(err, ct) { + if (err) { + callback(err); + return; + } + + // replace the encryptedPrivateKey with the double wrapped ciphertext + payload.encryptedPrivateKey = ct; + // set sessionId + payload.sessionId = authSessionKey.sessionId; + + // upload the encrypted priavet key + self._privateKeyDao.upload(payload, callback); + }); + }); + } + }; + + /** + * Request downloading the user's encrypted private key. This will initiate the server to send the recovery token via email/sms to the user. + * @param {String} options.userId The user's email address + * @param {String} options.keyId The private PGP key id + * @param {Function} callback(error) + */ + KeychainDAO.prototype.requestPrivateKeyDownload = function(options, callback) { + this._privateKeyDao.requestDownload(options, callback); + }; + + /** + * Download the encrypted private PGP key from the server using the recovery token. + * @param {String} options.userId The user's email address + * @param {String} options.keyId The user's email address + * @param {String} options.recoveryToken The recovery token acquired via email/sms from the key server + * @param {Function} callback(error, encryptedPrivateKey) + */ + KeychainDAO.prototype.downloadPrivateKey = function(options, callback) { + this._privateKeyDao.download(options, callback); + }; + + /** + * This is called after the encrypted private key has successfully been downloaded and it's ready to be decrypted and stored in localstorage. + * @param {String} options._id The private PGP key id + * @param {String} options.userId The user's email address + * @param {String} options.code The randomly generated or self selected code used to derive the key for the decryption of the private PGP key + * @param {String} options.encryptedPrivateKey The encrypted private PGP key + * @param {String} options.salt The salt required to derive the code derived key + * @param {String} options.iv The iv used to encrypt the private PGP key + * @param {Function} callback(error, keyObject) + */ + KeychainDAO.prototype.decryptAndStorePrivateKeyLocally = function(options, callback) { + var self = this, + code = options.code, + salt = options.salt, + keySize = config.symKeySize; + + if (!options._id || !options.userId || !options.code || !options.salt || !options.encryptedPrivateKey || !options.iv) { + callback(new Error('Incomplete arguments!')); + return; + } + + // derive key from the code and the salt using PBKDF2 + self._crypto.deriveKey(code, salt, keySize, function(err, key) { + if (err) { + callback(err); + return; + } + + decryptAndStore(key); + }); + + function decryptAndStore(derivedKey) { + // decrypt the private key with the derived key + var ct = options.encryptedPrivateKey, + iv = options.iv; + + self._crypto.decrypt(ct, derivedKey, iv, function(err, privateKeyArmored) { + if (err) { + callback(new Error('Invalid keychain code!')); + return; + } + + // validate pgp key + var keyParams; + try { + keyParams = self._pgp.getKeyParams(privateKeyArmored); + } catch (e) { + callback(new Error('Error parsing private PGP key!')); + return; + } + + if (keyParams._id !== options._id || keyParams.userId !== options.userId) { + callback(new Error('Private key parameters don\'t match with public key\'s!')); + return; + } + + var keyObject = { + _id: options._id, + userId: options.userId, + encryptedKey: privateKeyArmored + }; + + // store private key locally + self.saveLocalPrivateKey(keyObject, function(err) { + if (err) { + callback(err); + return; + } + + callback(null, keyObject); + }); + }); + } + }; + + // + // Keypair functions + // + /** * Gets the local user's key either from local storage * or fetches it from the cloud. The private key is encrypted. @@ -244,7 +744,7 @@ define(function(require) { var self = this; // search for user's public key locally - self._localDbDao.list('publickey', 0, null, function(err, allPubkeys) { + self._localDbDao.list(DB_PUBLICKEY, 0, null, function(err, allPubkeys) { if (err) { callback(err); return; @@ -364,7 +864,7 @@ define(function(require) { } // lookup in local storage - self._localDbDao.read('publickey_' + id, function(err, pubkey) { + self._localDbDao.read(DB_PUBLICKEY + '_' + id, function(err, pubkey) { if (err) { callback(err); return; @@ -400,29 +900,29 @@ define(function(require) { */ KeychainDAO.prototype.listLocalPublicKeys = function(callback) { // search local keyring for public key - this._localDbDao.list('publickey', 0, null, callback); + this._localDbDao.list(DB_PUBLICKEY, 0, null, callback); }; KeychainDAO.prototype.removeLocalPublicKey = function(id, callback) { - this._localDbDao.remove('publickey_' + id, callback); + this._localDbDao.remove(DB_PUBLICKEY + '_' + id, callback); }; KeychainDAO.prototype.lookupPrivateKey = function(id, callback) { // lookup in local storage - this._localDbDao.read('privatekey_' + id, callback); + this._localDbDao.read(DB_PRIVATEKEY + '_' + id, callback); }; KeychainDAO.prototype.saveLocalPublicKey = function(pubkey, callback) { // persist public key (email, _id) - var pkLookupKey = 'publickey_' + pubkey._id; + var pkLookupKey = DB_PUBLICKEY + '_' + pubkey._id; this._localDbDao.persist(pkLookupKey, pubkey, callback); }; KeychainDAO.prototype.saveLocalPrivateKey = function(privkey, callback) { // persist private key (email, _id) - var prkLookupKey = 'privatekey_' + privkey._id; + var prkLookupKey = DB_PRIVATEKEY + '_' + privkey._id; this._localDbDao.persist(prkLookupKey, privkey, callback); }; return KeychainDAO; -}); \ No newline at end of file +}); diff --git a/src/js/dao/privatekey-dao.js b/src/js/dao/privatekey-dao.js new file mode 100644 index 0000000..782965c --- /dev/null +++ b/src/js/dao/privatekey-dao.js @@ -0,0 +1,170 @@ +define(function() { + 'use strict'; + + var PrivateKeyDAO = function(restDao) { + this._restDao = restDao; + }; + + // + // Device registration functions + // + + /** + * Request registration of a new device by fetching registration session key. + * @param {String} options.userId The user's email address + * @param {String} options.deviceName The device's memorable name + * @param {Function} callback(error, regSessionKey) + * @return {Object} {encryptedRegSessionKey:[base64]} + */ + PrivateKeyDAO.prototype.requestDeviceRegistration = function(options, callback) { + var uri; + + if (!options.userId || !options.deviceName) { + callback(new Error('Incomplete arguments!')); + return; + } + + uri = '/device/user/' + options.userId + '/devicename/' + options.deviceName; + this._restDao.post(undefined, uri, callback); + }; + + /** + * Authenticate device registration by uploading the deviceSecret encrypted with the regSessionKeys. + * @param {String} options.userId The user's email address + * @param {String} options.deviceName The device's memorable name + * @param {String} options.encryptedDeviceSecret The base64 encoded encrypted device secret + * @param {String} options.iv The iv used for encryption + * @param {Function} callback(error) + */ + PrivateKeyDAO.prototype.uploadDeviceSecret = function(options, callback) { + var uri; + + if (!options.userId || !options.deviceName || !options.encryptedDeviceSecret || !options.iv) { + callback(new Error('Incomplete arguments!')); + return; + } + + uri = '/device/user/' + options.userId + '/devicename/' + options.deviceName; + this._restDao.put(options, uri, callback); + }; + + // + // Private key functions + // + + /** + * Request authSessionKeys required for upload the encrypted private PGP key. + * @param {String} options.userId The user's email address + * @param {Function} callback(error, authSessionKey) + * @return {Object} {sessionId, encryptedAuthSessionKey:[base64 encoded], encryptedChallenge:[base64 encoded]} + */ + PrivateKeyDAO.prototype.requestAuthSessionKey = function(options, callback) { + var uri; + + if (!options.userId) { + callback(new Error('Incomplete arguments!')); + return; + } + + uri = '/auth/user/' + options.userId; + this._restDao.post(undefined, uri, callback); + }; + + /** + * Verifiy authentication by uploading the challenge and deviceSecret encrypted with the authSessionKeys as a response. + * @param {String} options.userId The user's email address + * @param {String} options.encryptedChallenge The server's base64 encoded challenge encrypted using the authSessionKey + * @param {String} options.encryptedDeviceSecret The server's base64 encoded deviceSecret encrypted using the authSessionKey + * @param {String} options.iv The iv used for encryption + * @param {Function} callback(error) + */ + PrivateKeyDAO.prototype.verifyAuthentication = function(options, callback) { + var uri; + + if (!options.userId || !options.sessionId || !options.encryptedChallenge || !options.encryptedDeviceSecret || !options.iv) { + callback(new Error('Incomplete arguments!')); + return; + } + + uri = '/auth/user/' + options.userId + '/session/' + options.sessionId; + this._restDao.put(options, uri, callback); + }; + + /** + * Upload the encrypted private PGP key. + * @param {String} options._id The hex encoded capital 16 char key id + * @param {String} options.userId The user's email address + * @param {String} options.encryptedPrivateKey The base64 encoded encrypted private PGP key + * @param {String} options.sessionId The session id + * @param {Function} callback(error) + */ + PrivateKeyDAO.prototype.upload = function(options, callback) { + var uri; + + if (!options._id || !options.userId || !options.encryptedPrivateKey || !options.sessionId || !options.salt || !options.iv) { + callback(new Error('Incomplete arguments!')); + return; + } + + uri = '/privatekey/user/' + options.userId + '/session/' + options.sessionId; + this._restDao.post(options, uri, callback); + }; + + /** + * Request download for the encrypted private PGP key. + * @param {String} options.userId The user's email address + * @param {String} options.keyId The private PGP key id + * @param {Function} callback(error, found) + * @return {Boolean} weather the key was found on the server or not. + */ + PrivateKeyDAO.prototype.requestDownload = function(options, callback) { + var uri; + + if (!options.userId || !options.keyId) { + callback(new Error('Incomplete arguments!')); + return; + } + + uri = '/privatekey/user/' + options.userId + '/key/' + options.keyId; + this._restDao.get({ + uri: uri + }, function(err) { + // 404: there is no encrypted private key on the server + if (err && err.code !== 200) { + callback(null, false); + return; + } + + if (err) { + callback(err); + return; + } + + callback(null, true); + }); + }; + + /** + * Verify the download request for the private PGP key using the recovery token sent via email. This downloads the actual encrypted private key. + * @param {String} options.userId The user's email address + * @param {String} options.keyId The private key id + * @param {String} options.recoveryToken The token proving the user own the email account + * @param {Function} callback(error, encryptedPrivateKey) + * @return {Object} {_id:[hex encoded capital 16 char key id], encryptedPrivateKey:[base64 encoded], encryptedUserId: [base64 encoded]} + */ + PrivateKeyDAO.prototype.download = function(options, callback) { + var uri; + + if (!options.userId || !options.keyId || !options.recoveryToken) { + callback(new Error('Incomplete arguments!')); + return; + } + + uri = '/privatekey/user/' + options.userId + '/key/' + options.keyId + '/recovery/' + options.recoveryToken; + this._restDao.get({ + uri: uri + }, callback); + }; + + return PrivateKeyDAO; +}); \ No newline at end of file diff --git a/src/js/dao/rest-dao.js b/src/js/dao/rest-dao.js index 78f4236..686ebc1 100644 --- a/src/js/dao/rest-dao.js +++ b/src/js/dao/rest-dao.js @@ -17,7 +17,48 @@ define(function(require) { * @param {String} options.type (optional) The type of data that you're expecting back from the server: json, xml, text. Default: json. */ RestDAO.prototype.get = function(options, callback) { - var xhr, acceptHeader; + options.method = 'GET'; + this._processRequest(options, callback); + }; + + /** + * POST (create) request + */ + RestDAO.prototype.post = function(item, uri, callback) { + this._processRequest({ + method: 'POST', + payload: item, + uri: uri + }, callback); + }; + + /** + * PUT (update) request + */ + RestDAO.prototype.put = function(item, uri, callback) { + this._processRequest({ + method: 'PUT', + payload: item, + uri: uri + }, callback); + }; + + /** + * DELETE (remove) request + */ + RestDAO.prototype.remove = function(uri, callback) { + this._processRequest({ + method: 'DELETE', + uri: uri + }, callback); + }; + + // + // helper functions + // + + RestDAO.prototype._processRequest = function(options, callback) { + var xhr, format; if (typeof options.uri === 'undefined') { callback({ @@ -30,11 +71,11 @@ define(function(require) { options.type = options.type || 'json'; if (options.type === 'json') { - acceptHeader = 'application/json'; + format = 'application/json'; } else if (options.type === 'xml') { - acceptHeader = 'application/xml'; + format = 'application/xml'; } else if (options.type === 'text') { - acceptHeader = 'text/plain'; + format = 'text/plain'; } else { callback({ code: 400, @@ -44,14 +85,16 @@ define(function(require) { } xhr = new XMLHttpRequest(); - xhr.open('GET', this._baseUri + options.uri); - xhr.setRequestHeader('Accept', acceptHeader); + xhr.open(options.method, this._baseUri + options.uri); + xhr.setRequestHeader('Accept', format); + xhr.setRequestHeader('Content-Type', format); xhr.onload = function() { - if (xhr.readyState === 4 && xhr.status === 200) { - var res; + var res; + + if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 201 || xhr.status === 304)) { if (options.type === 'json') { - res = JSON.parse(xhr.responseText); + res = xhr.responseText ? JSON.parse(xhr.responseText) : xhr.responseText; } else { res = xhr.responseText; } @@ -69,72 +112,11 @@ define(function(require) { xhr.onerror = function() { callback({ code: 42, - errMsg: 'Error calling GET on ' + options.uri + errMsg: 'Error calling ' + options.method + ' on ' + options.uri }); }; - xhr.send(); - }; - - /** - * PUT (create/update) request - */ - RestDAO.prototype.put = function(item, uri, callback) { - var xhr; - - xhr = new XMLHttpRequest(); - xhr.open('PUT', this._baseUri + uri); - xhr.setRequestHeader('Content-Type', 'application/json'); - - xhr.onload = function() { - if (xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 201 || xhr.status === 304)) { - callback(null, xhr.responseText, xhr.status); - return; - } - - callback({ - code: xhr.status, - errMsg: xhr.statusText - }); - }; - - xhr.onerror = function() { - callback({ - errMsg: 'Error calling PUT on ' + uri - }); - }; - - xhr.send(JSON.stringify(item)); - }; - - /** - * DELETE (remove) request - */ - RestDAO.prototype.remove = function(uri, callback) { - var xhr; - - xhr = new XMLHttpRequest(); - xhr.open('DELETE', this._baseUri + uri); - - xhr.onload = function() { - if (xhr.readyState === 4 && xhr.status === 200) { - callback(null, xhr.responseText, xhr.status); - return; - } - - callback({ - code: xhr.status, - errMsg: xhr.statusText - }); - }; - - xhr.onerror = function() { - callback({ - errMsg: 'Error calling DELETE on ' + uri - }); - }; - - xhr.send(); + xhr.send(options.payload ? JSON.stringify(options.payload) : undefined); }; return RestDAO; diff --git a/src/lib/forge/forge.min.js b/src/lib/forge/forge.min.js index 3af6ed1..5d438fa 100644 --- a/src/lib/forge/forge.min.js +++ b/src/lib/forge/forge.min.js @@ -1 +1 @@ -(function(){var e,t,n;(function(r){function v(e,t){return h.call(e,t)}function m(e,t){var n,r,i,s,o,u,a,f,c,h,p,v=t&&t.split("/"),m=l.map,g=m&&m["*"]||{};if(e&&e.charAt(0)===".")if(t){v=v.slice(0,v.length-1),e=e.split("/"),o=e.length-1,l.nodeIdCompat&&d.test(e[o])&&(e[o]=e[o].replace(d,"")),e=v.concat(e);for(c=0;c0&&(e.splice(c-1,2),c-=2)}}e=e.join("/")}else e.indexOf("./")===0&&(e=e.substring(2));if((v||g)&&m){n=e.split("/");for(c=n.length;c>0;c-=1){r=n.slice(0,c).join("/");if(v)for(h=v.length;h>0;h-=1){i=m[v.slice(0,h).join("/")];if(i){i=i[r];if(i){s=i,u=c;break}}}if(s)break;!a&&g&&g[r]&&(a=g[r],f=c)}!s&&a&&(s=a,u=f),s&&(n.splice(0,u,s),e=n.join("/"))}return e}function g(e,t){return function(){return s.apply(r,p.call(arguments,0).concat([e,t]))}}function y(e){return function(t){return m(t,e)}}function b(e){return function(t){a[e]=t}}function w(e){if(v(f,e)){var t=f[e];delete f[e],c[e]=!0,i.apply(r,t)}if(!v(a,e)&&!v(c,e))throw new Error("No "+e);return a[e]}function E(e){var t,n=e?e.indexOf("!"):-1;return n>-1&&(t=e.substring(0,n),e=e.substring(n+1,e.length)),[t,e]}function S(e){return function(){return l&&l.config&&l.config[e]||{}}}var i,s,o,u,a={},f={},l={},c={},h=Object.prototype.hasOwnProperty,p=[].slice,d=/\.js$/;o=function(e,t){var n,r=E(e),i=r[0];return e=r[1],i&&(i=m(i,t),n=w(i)),i?n&&n.normalize?e=n.normalize(e,y(t)):e=m(e,t):(e=m(e,t),r=E(e),i=r[0],e=r[1],i&&(n=w(i))),{f:i?i+"!"+e:e,n:e,pr:i,p:n}},u={require:function(e){return g(e)},exports:function(e){var t=a[e];return typeof t!="undefined"?t:a[e]={}},module:function(e){return{id:e,uri:"",exports:a[e],config:S(e)}}},i=function(e,t,n,i){var s,l,h,p,d,m=[],y=typeof n,E;i=i||e;if(y==="undefined"||y==="function"){t=!t.length&&n.length?["require","exports","module"]:t;for(d=0;d0)t&1&&(n+=e),t>>>=1,t>0&&(e+=e);return this.data=n,this},t.ByteBuffer.prototype.putBytes=function(e){return this.data+=e,this},t.ByteBuffer.prototype.putString=function(e){return this.data+=t.encodeUtf8(e),this},t.ByteBuffer.prototype.putInt16=function(e){return this.data+=String.fromCharCode(e>>8&255)+String.fromCharCode(e&255),this},t.ByteBuffer.prototype.putInt24=function(e){return this.data+=String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255),this},t.ByteBuffer.prototype.putInt32=function(e){return this.data+=String.fromCharCode(e>>24&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255),this},t.ByteBuffer.prototype.putInt16Le=function(e){return this.data+=String.fromCharCode(e&255)+String.fromCharCode(e>>8&255),this},t.ByteBuffer.prototype.putInt24Le=function(e){return this.data+=String.fromCharCode(e&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e>>16&255),this},t.ByteBuffer.prototype.putInt32Le=function(e){return this.data+=String.fromCharCode(e&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>24&255),this},t.ByteBuffer.prototype.putInt=function(e,t){do t-=8,this.data+=String.fromCharCode(e>>t&255);while(t>0);return this},t.ByteBuffer.prototype.putSignedInt=function(e,t){return e<0&&(e+=2<0);return t},t.ByteBuffer.prototype.getSignedInt=function(e){var t=this.getInt(e),n=2<=n&&(t-=n<<1),t},t.ByteBuffer.prototype.getBytes=function(e){var t;return e?(e=Math.min(this.length(),e),t=this.data.slice(this.read,this.read+e),this.read+=e):e===0?t="":(t=this.read===0?this.data:this.data.slice(this.read),this.clear()),t},t.ByteBuffer.prototype.bytes=function(e){return typeof e=="undefined"?this.data.slice(this.read):this.data.slice(this.read,this.read+e)},t.ByteBuffer.prototype.at=function(e){return this.data.charCodeAt(this.read+e)},t.ByteBuffer.prototype.setAt=function(e,t){return this.data=this.data.substr(0,this.read+e)+String.fromCharCode(t)+this.data.substr(this.read+e+1),this},t.ByteBuffer.prototype.last=function(){return this.data.charCodeAt(this.data.length-1)},t.ByteBuffer.prototype.copy=function(){var e=t.createBuffer(this.data);return e.read=this.read,e},t.ByteBuffer.prototype.compact=function(){return this.read>0&&(this.data=this.data.slice(this.read),this.read=0),this},t.ByteBuffer.prototype.clear=function(){return this.data="",this.read=0,this},t.ByteBuffer.prototype.truncate=function(e){var t=Math.max(0,this.length()-e);return this.data=this.data.substr(this.read,t),this.read=0,this},t.ByteBuffer.prototype.toHex=function(){var e="";for(var t=this.read;t0)t&1&&(n+=e),t>>>=1,t>0&&(e+=e);return n},t.xorBytes=function(e,t,n){var r="",i="",s="",o=0,u=0;for(;n>0;--n,++o)i=e.charCodeAt(o)^t.charCodeAt(o),u>=10&&(r+=s,s="",u=0),s+=String.fromCharCode(i),++u;return r+=s,r},t.hexToBytes=function(e){var t="",n=0;e.length&!0&&(n=1,t+=String.fromCharCode(parseInt(e[0],16)));for(;n>24&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255)};var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",i=[62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];t.encode64=function(e,t){var n="",i="",s,o,u,a=0;while(a>2),n+=r.charAt((s&3)<<4|o>>4),isNaN(o)?n+="==":(n+=r.charAt((o&15)<<2|u>>6),n+=isNaN(u)?"=":r.charAt(u&63)),t&&n.length>t&&(i+=n.substr(0,t)+"\r\n",n=n.substr(t));return i+=n,i},t.decode64=function(e){e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");var t="",n,r,s,o,u=0;while(u>4),s!==64&&(t+=String.fromCharCode((r&15)<<4|s>>2),o!==64&&(t+=String.fromCharCode((s&3)<<6|o)));return t},t.encodeUtf8=function(e){return unescape(encodeURIComponent(e))},t.decodeUtf8=function(e){return decodeURIComponent(escape(e))},t.deflate=function(e,n,r){n=t.decode64(e.deflate(t.encode64(n)).rval);if(r){var i=2,s=n.charCodeAt(1);s&32&&(i=6),n=n.substring(i,n.length-4)}return n},t.inflate=function(e,n,r){var i=e.inflate(t.encode64(n)).rval;return i===null?null:t.decode64(i)};var s=function(e,n,r){if(!e)throw{message:"WebStorage not available."};var i;r===null?i=e.removeItem(n):(r=t.encode64(JSON.stringify(r)),i=e.setItem(n,r));if(typeof i!="undefined"&&i.rval!==!0)throw i.error},o=function(e,n){if(!e)throw{message:"WebStorage not available."};var r=e.getItem(n);if(e.init)if(r.rval===null){if(r.error)throw r.error;r=null}else r=r.rval;return r!==null&&(r=JSON.parse(t.decode64(r))),r},u=function(e,t,n,r){var i=o(e,t);i===null&&(i={}),i[n]=r,s(e,t,i)},a=function(e,t,n){var r=o(e,t);return r!==null&&(r=n in r?r[n]:null),r},f=function(e,t,n){var r=o(e,t);if(r!==null&&n in r){delete r[n];var i=!0;for(var u in r){i=!1;break}i&&(r=null),s(e,t,r)}},l=function(e,t){s(e,t,null)},c=function(e,t,n){var r=null;typeof n=="undefined"&&(n=["web","flash"]);var i,s=!1,o=null;for(var u in n){i=n[u];try{if(i==="flash"||i==="both"){if(t[0]===null)throw{message:"Flash local storage not available."};r=e.apply(this,t),s=i==="flash"}if(i==="web"||i==="both")t[0]=localStorage,r=e.apply(this,t),s=!0}catch(a){o=a}if(s)break}if(!s)throw o;return r};t.setItem=function(e,t,n,r,i){c(u,arguments,i)},t.getItem=function(e,t,n,r){return c(a,arguments,r)},t.removeItem=function(e,t,n,r){c(f,arguments,r)},t.clearItems=function(e,t,n){c(l,arguments,n)},t.parseUrl=function(e){var t=/^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g;t.lastIndex=0;var n=t.exec(e),r=n===null?null:{full:e,scheme:n[1],host:n[2],port:n[3],path:n[4]};return r&&(r.fullHost=r.host,r.port?r.port!==80&&r.scheme==="http"?r.fullHost+=":"+r.port:r.port!==443&&r.scheme==="https"&&(r.fullHost+=":"+r.port):r.scheme==="http"?r.port=80:r.scheme==="https"&&(r.port=443),r.full=r.scheme+"://"+r.fullHost),r};var h=null;t.getQueryVariables=function(e){var t=function(e){var t={},n=e.split("&");for(var r=0;r0?(s=n[r].substring(0,i),o=n[r].substring(i+1)):(s=n[r],o=null),s in t||(t[s]=[]),!(s in Object.prototype)&&o!==null&&t[s].push(unescape(o))}return t},n;return typeof e=="undefined"?(h===null&&(typeof window=="undefined"?h={}:h=t(window.location.search.substring(1))),n=h):n=t(e),n},t.parseFragment=function(e){var n=e,r="",i=e.indexOf("?");i>0&&(n=e.substring(0,i),r=e.substring(i+1));var s=n.split("/");s.length>0&&s[0]===""&&s.shift();var o=r===""?{}:t.getQueryVariables(r);return{pathString:n,queryString:r,path:s,query:o}},t.makeRequest=function(e){var n=t.parseFragment(e),r={path:n.pathString,query:n.queryString,getPath:function(e){return typeof e=="undefined"?n.path:n.path[e]},getQuery:function(e,t){var r;return typeof e=="undefined"?r=n.query:(r=n.query[e],r&&typeof t!="undefined"&&(r=r[t])),r},getQueryLast:function(e,t){var n,i=r.getQuery(e);return i?n=i[i.length-1]:n=t,n}};return r},t.makeLink=function(e,t,n){e=jQuery.isArray(e)?e.join("/"):e;var r=jQuery.param(t||{});return n=n||"",e+(r.length>0?"?"+r:"")+(n.length>0?"#"+n:"")},t.setPath=function(e,t,n){if(typeof e=="object"&&e!==null){var r=0,i=t.length;while(r0&&s.push(r),o=t.lastIndex;var u=n[0][1];switch(u){case"s":case"o":i");break;case"%":s.push("%");break;default:s.push("<%"+u+"?>")}}return s.push(e.substring(o)),s.join("")},t.formatNumber=function(e,t,n,r){var i=e,s=isNaN(t=Math.abs(t))?2:t,o=n===undefined?",":n,u=r===undefined?".":r,a=i<0?"-":"",f=parseInt(i=Math.abs(+i||0).toFixed(s),10)+"",l=f.length>3?f.length%3:0;return a+(l?f.substr(0,l)+u:"")+f.substr(l).replace(/(\d{3})(?=\d)/g,"$1"+u)+(s?o+Math.abs(i-f).toFixed(s).slice(2):"")},t.formatSize=function(e){return e>=1073741824?e=t.formatNumber(e/1073741824,2,".","")+" GiB":e>=1048576?e=t.formatNumber(e/1048576,2,".","")+" MiB":e>=1024?e=t.formatNumber(e/1024,0)+" KiB":e=t.formatNumber(e,0)+" bytes",e},t.bytesFromIP=function(e){return e.indexOf(".")!==-1?t.bytesFromIPv4(e):e.indexOf(":")!==-1?t.bytesFromIPv6(e):null},t.bytesFromIPv4=function(e){e=e.split(".");if(e.length!==4)return null;var n=t.createBuffer();for(var r=0;rr[i].end-r[i].start&&(i=r.length-1))}n.push(o)}if(r.length>0){var f=r[i];f.end-f.start>0&&(n.splice(f.start,f.end-f.start+1,""),f.start===0&&n.unshift(""),f.end===7&&n.push(""))}return n.join(":")},t.estimateCores=function(e,n){function i(e,u,a){if(u===0){var f=Math.floor(e.reduce(function(e,t){return e+t},0)/e.length);return t.cores=Math.max(1,f),URL.revokeObjectURL(r),n(null,t.cores)}s(a,function(t,n){e.push(o(a,n)),i(e,u-1,a)})}function s(e,t){var n=[],i=[];for(var s=0;su.st&&i.sti.st&&u.st>8^p&255^99,r[a]=p,i[p]=a,d=e[p],l=e[a],c=e[l],h=e[c],v=d<<24^p<<16^p<<8^(p^d),m=(l^c^h)<<24^(a^h)<<16^(a^c^h)<<8^(a^l^h);for(var g=0;g<4;++g)o[g][a]=v,u[g][p]=m,v=v<<24|v>>>8,m=m<<24|m>>>8;a===0?a=f=1:(a=l^e[e[e[l^h]]],f^=e[e[f]])}},f=function(e,t){var i=e.slice(0),o,a=1,f=i.length,l=f+6+1,c=n*l;for(var h=f;h>>16&255]<<24^r[o>>>8&255]<<16^r[o&255]<<8^r[o>>>24]^s[a]<<24,a++):f>6&&h%f===4&&(o=r[o>>>24]<<24^r[o>>>16&255]<<16^r[o>>>8&255]<<8^r[o&255]),i[h]=i[h-f]^o;if(t){var p,d=u[0],v=u[1],m=u[2],g=u[3],y=i.slice(0),c=i.length;for(var h=0,b=c-n;h>>24]]^v[r[p>>>16&255]]^m[r[p>>>8&255]]^g[r[p&255]];i=y}return i},l=function(e,t,n,s){var a=e.length/4-1,f,l,c,h,p;s?(f=u[0],l=u[1],c=u[2],h=u[3],p=i):(f=o[0],l=o[1],c=o[2],h=o[3],p=r);var d,v,m,g,y,b,w;d=t[0]^e[0],v=t[s?3:1]^e[1],m=t[2]^e[2],g=t[s?1:3]^e[3];var E=3;for(var S=1;S>>24]^l[v>>>16&255]^c[m>>>8&255]^h[g&255]^e[++E],b=f[v>>>24]^l[m>>>16&255]^c[g>>>8&255]^h[d&255]^e[++E],w=f[m>>>24]^l[g>>>16&255]^c[d>>>8&255]^h[v&255]^e[++E],g=f[g>>>24]^l[d>>>16&255]^c[v>>>8&255]^h[m&255]^e[++E],d=y,v=b,m=w;n[0]=p[d>>>24]<<24^p[v>>>16&255]<<16^p[m>>>8&255]<<8^p[g&255]^e[++E],n[s?3:1]=p[v>>>24]<<24^p[m>>>16&255]<<16^p[g>>>8&255]<<8^p[d&255]^e[++E],n[2]=p[m>>>24]<<24^p[g>>>16&255]<<16^p[d>>>8&255]<<8^p[v&255]^e[++E],n[s?1:3]=p[g>>>24]<<24^p[d>>>16&255]<<16^p[v>>>8&255]<<8^p[m&255]^e[++E]},c=function(r,i,s,o,u){function C(){if(o)for(var e=0;e=0;--e){if(E[e]!==4294967295){++E[e];break}E[e]=0}for(var e=0;e>>=2;for(var p=0;p=y||b.length()>0&&T)N()},c.finish=function(e){var t=!0,r=b.length()%y;if(!o)if(e)t=e(y,b,o);else if(m){var i=b.length()===y?y:y-b.length();b.fillWithByte(i,i)}t&&(T=!0,c.update());if(o){m&&(t=r===0);if(t)if(e)t=e(y,w,o);else if(m){var s=w.length(),u=w.at(s-1);u>n<<2?t=!1:w.truncate(u)}}return!m&&!e&&r>0&&w.truncate(y-r),t},c.start=function(t,r){t===null&&(t=x.slice(0));if(typeof t=="string"&&t.length===16)t=e.util.createBuffer(t);else if(e.util.isArray(t)&&t.length===16){var i=t,t=e.util.createBuffer();for(var s=0;s<16;++s)t.putByte(i[s])}if(!e.util.isArray(t)){var i=t;t=new Array(4),t[0]=i.getInt32(),t[1]=i.getInt32(),t[2]=i.getInt32(),t[3]=i.getInt32()}b=e.util.createBuffer(),w=r||e.util.createBuffer(),x=t.slice(0),E=new Array(n),S=new Array(n),T=!1,c.output=w;if(["CFB","OFB","CTR"].indexOf(u)!==-1){for(var s=0;s1){var h=r.read,p=r.getByte();if(p===0){s=r.getByte();var d=s&192;if(d===t.Class.UNIVERSAL||d===t.Class.CONTEXT_SPECIFIC)try{var v=n(r);c=v===a-(r.read-h),c&&(++h,--a)}catch(m){}}r.read=h}if(c){f=[];if(a===undefined)for(;;){if(r.bytes(2)===String.fromCharCode(0,0)){r.getBytes(2);break}f.push(t.fromDer(r,i))}else{var g=r.length();while(a>0)f.push(t.fromDer(r,i)),a-=g-r.length(),g=r.length()}}else{if(a===undefined){if(i)throw{message:"Non-constructed ASN.1 object of indefinite length."};a=r.length()}if(u===t.Type.BMPSTRING){f="";for(var y=0;y>>=8;while(u>0);r.putByte(a.length|128);for(var o=a.length-1;o>=0;--o)r.putByte(a.charCodeAt(o))}return r.putBuffer(s),r},t.oidToDer=function(t){var n=t.split("."),r=e.util.createBuffer();r.putByte(40*parseInt(n[0],10)+parseInt(n[1],10));var i,s,o,u;for(var a=2;a>>=7,i||(u|=128),s.push(u),i=!1;while(o>0);for(var f=s.length-1;f>=0;--f)r.putByte(s[f])}return r},t.derToOid=function(t){var n;typeof t=="string"&&(t=e.util.createBuffer(t));var r=t.getByte();n=Math.floor(r/40)+"."+r%40;var i=0;while(t.length()>0)r=t.getByte(),i<<=7,r&128?i+=r&127:(n+="."+(i+r),i=0);return n},t.utcTimeToDate=function(e){var t=new Date,n=parseInt(e.substr(0,2),10);n=n>=50?1900+n:2e3+n;var r=parseInt(e.substr(2,2),10)-1,i=parseInt(e.substr(4,2),10),s=parseInt(e.substr(6,2),10),o=parseInt(e.substr(8,2),10),u=0;if(e.length>11){var a=e.charAt(10),f=10;a!=="+"&&a!=="-"&&(u=parseInt(e.substr(10,2),10),f+=2)}t.setUTCFullYear(n,r,i),t.setUTCHours(s,o,u,0);if(f){a=e.charAt(f);if(a==="+"||a==="-"){var l=parseInt(e.substr(f+1,2),10),c=parseInt(e.substr(f+4,2),10),h=l*60+c;h*=6e4,a==="+"?t.setTime(+t-h):t.setTime(+t+h)}}return t},t.generalizedTimeToDate=function(e){var t=new Date,n=parseInt(e.substr(0,4),10),r=parseInt(e.substr(4,2),10)-1,i=parseInt(e.substr(6,2),10),s=parseInt(e.substr(8,2),10),o=parseInt(e.substr(10,2),10),u=parseInt(e.substr(12,2),10),a=0,f=0,l=!1;e.charAt(e.length-1)==="Z"&&(l=!0);var c=e.length-5,h=e.charAt(c);if(h==="+"||h==="-"){var p=parseInt(e.substr(c+1,2),10),d=parseInt(e.substr(c+4,2),10);f=p*60+d,f*=6e4,h==="+"&&(f*=-1),l=!0}return e.charAt(14)==="."&&(a=parseFloat(e.substr(14),10)*1e3),l?(t.setUTCFullYear(n,r,i),t.setUTCHours(s,o,u,a),t.setTime(+t+f)):(t.setFullYear(n,r,i),t.setHours(s,o,u,a)),t},t.dateToUtcTime=function(e){var t="",n=[];n.push((""+e.getUTCFullYear()).substr(2)),n.push(""+(e.getUTCMonth()+1)),n.push(""+e.getUTCDate()),n.push(""+e.getUTCHours()),n.push(""+e.getUTCMinutes()),n.push(""+e.getUTCSeconds());for(var r=0;r=-128&&t<128)return n.putSignedInt(t,8);if(t>=-32768&&t<32768)return n.putSignedInt(t,16);if(t>=-8388608&&t<8388608)return n.putSignedInt(t,24);if(t>=-2147483648&&t<2147483648)return n.putSignedInt(t,32);throw{message:"Integer too large; max is 32-bits.",integer:t}},t.derToInteger=function(t){typeof t=="string"&&(t=e.util.createBuffer(t));var n=t.length()*8;if(n>32)throw{message:"Integer too large; max is 32-bits."};return t.getSignedInt(n)},t.validate=function(n,r,i,s){var o=!1;if(n.tagClass!==r.tagClass&&typeof r.tagClass!="undefined"||n.type!==r.type&&typeof r.type!="undefined")s&&(n.tagClass!==r.tagClass&&s.push("["+r.name+"] "+'Expected tag class "'+r.tagClass+'", got "'+n.tagClass+'"'),n.type!==r.type&&s.push("["+r.name+"] "+'Expected type "'+r.type+'", got "'+n.type+'"'));else if(n.constructed===r.constructed||typeof r.constructed=="undefined"){o=!0;if(r.value&&e.util.isArray(r.value)){var u=0;for(var a=0;o&&a0&&(o+="\n");var u="";for(var a=0;a=64){u=e.h0,a=e.h1,f=e.h2,l=e.h3;for(p=0;p<16;++p)t[p]=n.getInt32Le(),c=l^a&(f^l),o=u+c+s[p]+t[p],h=i[p],u=l,l=f,f=a,a+=o<>>32-h;for(;p<32;++p)c=f^l&(a^f),o=u+c+s[p]+t[r[p]],h=i[p],u=l,l=f,f=a,a+=o<>>32-h;for(;p<48;++p)c=a^f^l,o=u+c+s[p]+t[r[p]],h=i[p],u=l,l=f,f=a,a+=o<>>32-h;for(;p<64;++p)c=f^(a|~l),o=u+c+s[p]+t[r[p]],h=i[p],u=l,l=f,f=a,a+=o<>>32-h;e.h0=e.h0+u&4294967295,e.h1=e.h1+a&4294967295,e.h2=e.h2+f&4294967295,e.h3=e.h3+l&4294967295,d-=64}};t.create=function(){o||u();var t=null,r=e.util.createBuffer(),i=new Array(16),s={algorithm:"md5",blockLength:64,digestLength:16,messageLength:0};return s.start=function(){return s.messageLength=0,r=e.util.createBuffer(),t={h0:1732584193,h1:4023233417,h2:2562383102,h3:271733878},s},s.start(),s.update=function(n,o){return o==="utf8"&&(n=e.util.encodeUtf8(n)),s.messageLength+=n.length,r.putBytes(n),a(t,i,r),(r.read>2048||r.length()===0)&&r.compact(),s},s.digest=function(){var o=s.messageLength,u=e.util.createBuffer();u.putBytes(r.bytes()),u.putBytes(n.substr(0,64-(o+8)%64)),u.putInt32Le(o<<3&4294967295),u.putInt32Le(o>>>29&255);var f={h0:t.h0,h1:t.h1,h2:t.h2,h3:t.h3};a(f,i,u);var l=e.util.createBuffer();return l.putInt32Le(f.h0),l.putInt32Le(f.h1),l.putInt32Le(f.h2),l.putInt32Le(f.h3),l},s}}var r="md5";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=64){i=e.h0,s=e.h1,o=e.h2,u=e.h3,a=e.h4;for(l=0;l<16;++l)r=n.getInt32(),t[l]=r,f=u^s&(o^u),r=(i<<5|i>>>27)+f+a+1518500249+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<20;++l)r=t[l-3]^t[l-8]^t[l-14]^t[l-16],r=r<<1|r>>>31,t[l]=r,f=u^s&(o^u),r=(i<<5|i>>>27)+f+a+1518500249+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<32;++l)r=t[l-3]^t[l-8]^t[l-14]^t[l-16],r=r<<1|r>>>31,t[l]=r,f=s^o^u,r=(i<<5|i>>>27)+f+a+1859775393+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<40;++l)r=t[l-6]^t[l-16]^t[l-28]^t[l-32],r=r<<2|r>>>30,t[l]=r,f=s^o^u,r=(i<<5|i>>>27)+f+a+1859775393+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<60;++l)r=t[l-6]^t[l-16]^t[l-28]^t[l-32],r=r<<2|r>>>30,t[l]=r,f=s&o|u&(s^o),r=(i<<5|i>>>27)+f+a+2400959708+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<80;++l)r=t[l-6]^t[l-16]^t[l-28]^t[l-32],r=r<<2|r>>>30,t[l]=r,f=s^o^u,r=(i<<5|i>>>27)+f+a+3395469782+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;e.h0+=i,e.h1+=s,e.h2+=o,e.h3+=u,e.h4+=a,c-=64}};t.create=function(){r||i();var t=null,o=e.util.createBuffer(),u=new Array(80),a={algorithm:"sha1",blockLength:64,digestLength:20,messageLength:0};return a.start=function(){return a.messageLength=0,o=e.util.createBuffer(),t={h0:1732584193,h1:4023233417,h2:2562383102,h3:271733878,h4:3285377520},a},a.start(),a.update=function(n,r){return r==="utf8"&&(n=e.util.encodeUtf8(n)),a.messageLength+=n.length,o.putBytes(n),s(t,u,o),(o.read>2048||o.length()===0)&&o.compact(),a},a.digest=function(){var r=a.messageLength,i=e.util.createBuffer();i.putBytes(o.bytes()),i.putBytes(n.substr(0,64-(r+8)%64)),i.putInt32(r>>>29&255),i.putInt32(r<<3&4294967295);var f={h0:t.h0,h1:t.h1,h2:t.h2,h3:t.h3,h4:t.h4};s(f,u,i);var l=e.util.createBuffer();return l.putInt32(f.h0),l.putInt32(f.h1),l.putInt32(f.h2),l.putInt32(f.h3),l.putInt32(f.h4),l},a}}var r="sha1";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=64){for(l=0;l<16;++l)t[l]=n.getInt32();for(;l<64;++l)r=t[l-2],r=(r>>>17|r<<15)^(r>>>19|r<<13)^r>>>10,s=t[l-15],s=(s>>>7|s<<25)^(s>>>18|s<<14)^s>>>3,t[l]=r+t[l-7]+s+t[l-16]&4294967295;c=e.h0,h=e.h1,p=e.h2,d=e.h3,v=e.h4,m=e.h5,g=e.h6,y=e.h7;for(l=0;l<64;++l)u=(v>>>6|v<<26)^(v>>>11|v<<21)^(v>>>25|v<<7),a=g^v&(m^g),o=(c>>>2|c<<30)^(c>>>13|c<<19)^(c>>>22|c<<10),f=c&h|p&(c^h),r=y+u+a+i[l]+t[l],s=o+f,y=g,g=m,m=v,v=d+r&4294967295,d=p,p=h,h=c,c=r+s&4294967295;e.h0=e.h0+c&4294967295,e.h1=e.h1+h&4294967295,e.h2=e.h2+p&4294967295,e.h3=e.h3+d&4294967295,e.h4=e.h4+v&4294967295,e.h5=e.h5+m&4294967295,e.h6=e.h6+g&4294967295,e.h7=e.h7+y&4294967295,b-=64}};t.create=function(){r||s();var t=null,i=e.util.createBuffer(),u=new Array(64),a={algorithm:"sha256",blockLength:64,digestLength:32,messageLength:0};return a.start=function(){return a.messageLength=0,i=e.util.createBuffer(),t={h0:1779033703,h1:3144134277,h2:1013904242,h3:2773480762,h4:1359893119,h5:2600822924,h6:528734635,h7:1541459225},a},a.start(),a.update=function(n,r){return r==="utf8"&&(n=e.util.encodeUtf8(n)),a.messageLength+=n.length,i.putBytes(n),o(t,u,i),(i.read>2048||i.length()===0)&&i.compact(),a},a.digest=function(){var r=a.messageLength,s=e.util.createBuffer();s.putBytes(i.bytes()),s.putBytes(n.substr(0,64-(r+8)%64)),s.putInt32(r>>>29&255),s.putInt32(r<<3&4294967295);var f={h0:t.h0,h1:t.h1,h2:t.h2,h3:t.h3,h4:t.h4,h5:t.h5,h6:t.h6,h7:t.h7};o(f,u,s);var l=e.util.createBuffer();return l.putInt32(f.h0),l.putInt32(f.h1),l.putInt32(f.h2),l.putInt32(f.h3),l.putInt32(f.h4),l.putInt32(f.h5),l.putInt32(f.h6),l.putInt32(f.h7),l},a}}var r="sha256";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;on.blockLength&&(n.start(),n.update(o.bytes()),o=n.digest()),r=e.util.createBuffer(),i=e.util.createBuffer(),f=o.length();for(var a=0;a65&&s!==-1){var o=t[s];o===","?(++s,t=t.substr(0,s)+"\r\n "+t.substr(s)):t=t.substr(0,s)+"\r\n"+o+t.substr(s+1),i=r-s-1,s=-1,++r}else if(t[r]===" "||t[r]===" "||t[r]===",")s=r;return t}function r(e){return e.replace(/^\s+/,"")}var t=e.pem=e.pem||{};t.encode=function(t,r){r=r||{};var i="-----BEGIN "+t.type+"-----\r\n",s;t.procType&&(s={name:"Proc-Type",values:[String(t.procType.version),t.procType.type]},i+=n(s)),t.contentDomain&&(s={name:"Content-Domain",values:[t.contentDomain]},i+=n(s)),t.dekInfo&&(s={name:"DEK-Info",values:[t.dekInfo.algorithm]},t.dekInfo.parameters&&s.values.push(t.dekInfo.parameters),i+=n(s));if(t.headers)for(var o=0;o8?3:1,m=[],g=[0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0],y=0,b;for(var w=0;w>>4^S)&252645135,S^=b,E^=b<<4,b=(S>>>-16^E)&65535,E^=b,S^=b<<-16,b=(E>>>2^S)&858993459,S^=b,E^=b<<2,b=(S>>>-16^E)&65535,E^=b,S^=b<<-16,b=(E>>>1^S)&1431655765,S^=b,E^=b<<1,b=(S>>>8^E)&16711935,E^=b,S^=b<<8,b=(E>>>1^S)&1431655765,S^=b,E^=b<<1,b=E<<8|S>>>20&240,E=S<<24|S<<8&16711680|S>>>8&65280|S>>>24&240,S=b;for(var x=0;x>>26,S=S<<2|S>>>26):(E=E<<1|E>>>27,S=S<<1|S>>>27),E&=-15,S&=-15;var T=t[E>>>28]|n[E>>>24&15]|r[E>>>20&15]|i[E>>>16&15]|s[E>>>12&15]|o[E>>>8&15]|u[E>>>4&15],N=a[S>>>28]|f[S>>>24&15]|l[S>>>20&15]|c[S>>>16&15]|h[S>>>12&15]|p[S>>>8&15]|d[S>>>4&15];b=(N>>>16^T)&65535,m[y++]=T^b,m[y++]=N^b<<16}}return m}var t=[16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028,16778240,16778240,0,65540,66560,0,16842756],n=[-2146402272,-2147450880,32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576,-2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880,32800,-2147483648,-2146435040,-2146402272,1081344],r=[520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072,134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800,131592,8,134348808,131584],i=[8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928],s=[256,34078976,34078720,1107296512,524288,256,1073741824,34078720,1074266368,524288,33554688,1074266368,1107296512,1107820544,524544,1073741824,33554432,1074266112,1074266112,0,1073742080,1107820800,1107820800,33554688,1107820544,1073742080,0,1107296256,34078976,33554432,1107296256,524544,524288,1107296512,256,33554432,1073741824,34078720,1107296512,1074266368,33554688,1073741824,1107820544,34078976,1074266368,256,33554432,1107820544,1107820800,524544,1107296256,1107820800,34078720,0,1074266112,1107296256,524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080],o=[536870928,541065216,16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384,541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312],u=[2097152,69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066,0,2099202,69206016,2048,67108866,67110912,2048,2097154],a=[268439616,4096,262144,268701760,268435456,268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240,266240,4160,4160,262208,268435456,268701696],l=function(l,c){typeof l=="string"&&(l.length===8||l.length===24)&&(l=e.util.createBuffer(l));var h=f(l),p=1,d=0,v=0,m=0,g=0,y=!1,b=null,w=null,E=h.length===32?3:9,S;E===3?S=c?[0,32,2]:[30,-2,-2]:S=c?[0,32,2,62,30,-2,64,96,2]:[94,62,-2,32,64,2,30,-2,-2];var x=null;return x={start:function(t,n){t?(typeof t=="string"&&t.length===8&&(t=e.util.createBuffer(t)),p=1,d=t.getInt32(),m=t.getInt32()):p=0,y=!1,b=e.util.createBuffer(),w=n||e.util.createBuffer(),x.output=w},update:function(e){y||b.putBuffer(e);while(b.length()>=8){var f,l=b.getInt32(),x=b.getInt32();p===1&&(c?(l^=d,x^=m):(v=d,g=m,d=l,m=x)),f=(l>>>4^x)&252645135,x^=f,l^=f<<4,f=(l>>>16^x)&65535,x^=f,l^=f<<16,f=(x>>>2^l)&858993459,l^=f,x^=f<<2,f=(x>>>8^l)&16711935,l^=f,x^=f<<8,f=(l>>>1^x)&1431655765,x^=f,l^=f<<1,l=l<<1|l>>>31,x=x<<1|x>>>31;for(var T=0;T>>4|x<<28)^h[k+1];f=l,l=x,x=f^(n[L>>>24&63]|i[L>>>16&63]|o[L>>>8&63]|a[L&63]|t[A>>>24&63]|r[A>>>16&63]|s[A>>>8&63]|u[A&63])}f=l,l=x,x=f}l=l>>>1|l<<31,x=x>>>1|x<<31,f=(l>>>1^x)&1431655765,x^=f,l^=f<<1,f=(x>>>8^l)&16711935,l^=f,x^=f<<8,f=(x>>>2^l)&858993459,l^=f,x^=f<<2,f=(l>>>16^x)&65535,x^=f,l^=f<<16,f=(l>>>4^x)&252645135,x^=f,l^=f<<4,p===1&&(c?(d=l,m=x):(l^=v,x^=g)),w.putInt32(l),w.putInt32(x)}},finish:function(e){var t=!0;if(c)if(e)t=e(8,b,!c);else{var n=b.length()===8?8:8-b.length();b.fillWithByte(n,n)}t&&(y=!0,x.update());if(!c){t=b.length()===0;if(t)if(e)t=e(8,w,!c);else{var r=w.length(),i=w.at(r-1);i>r?t=!1:w.truncate(i)}}return t}},x};e.des=e.des||{},e.des.startEncrypting=function(e,t,n){var r=l(e,!0);return r.start(t,n),r},e.des.createEncryptionCipher=function(e){return l(e,!0)},e.des.startDecrypting=function(e,t,n){var r=l(e,!1);return r.start(t,n),r},e.des.createDecryptionCipher=function(e){return l(e,!1)}}var r="des";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o4294967295*o)throw{message:"Derived key is too long."};var u=Math.ceil(i/o),a=i-(u-1)*o,f=e.hmac.create();f.start(s,t);var l="",c,h,p;for(var d=1;d<=u;++d){f.start(null,null),f.update(n),f.update(e.util.int32ToBytes(d)),c=p=f.digest().getBytes();for(var v=2;v<=r;++v)f.start(null,null),f.update(p),h=f.digest().getBytes(),c=e.util.xorBytes(c,h,o),p=h;l+=d=32)return f(),e();var t=32-n.pools[0].messageLength<<5;n.seedFile(t,function(t,r){if(t)return e(t);n.collect(r),f(),e()})}function a(){if(n.pools[0].messageLength>=32)return f();var e=32-n.pools[0].messageLength<<5;n.collect(n.seedFileSync(e)),f()}function f(){var t=e.md.sha1.create();t.update(n.pools[0].digest().getBytes()),n.pools[0].start();var r=1;for(var i=1;i<32;++i)r=r===31?2147483648:r<<2,r%n.reseeds===0&&(t.update(n.pools[i].digest().getBytes()),n.pools[i].start());var s=t.digest().getBytes();t.start(),t.update(s);var o=t.digest().getBytes();n.key=n.plugin.formatKey(s),n.seed=n.plugin.formatSeed(o),++n.reseeds,n.generated=0,n.time=+(new Date)}function l(t){var n=null;if(typeof window!="undefined"){var r=window.crypto||window.msCrypto;r&&r.getRandomValues&&(n=function(e){return r.getRandomValues(e)})}var i=e.util.createBuffer();if(n)while(i.length()>16),l+=(f&32767)<<16,l+=f>>15,l=(l&2147483647)+(l>>31),h=l&4294967295;for(var u=0;u<3;++u)c=h>>>(u<<3),c^=Math.floor(Math.random()*256),i.putByte(String.fromCharCode(c&255))}}return i.getBytes(t)}var n={plugin:t,key:null,seed:null,time:null,reseeds:0,generated:0},i=t.md,s=new Array(32);for(var o=0;o<32;++o)s[o]=i.create();return n.pools=s,n.pool=0,n.generate=function(t,r){function l(c){if(c)return r(c);if(f.length()>=t)return r(null,f.getBytes(t));if(n.generated>=1048576){var h=+(new Date);if(n.time===null||h-n.time>100)n.key=null}if(n.key===null)return u(l);var p=i(n.key,n.seed);n.generated+=p.length,f.putBytes(p),n.key=o(i(n.key,s(n.seed))),n.seed=a(i(n.key,n.seed)),e.util.setImmediate(l)}if(!r)return n.generateSync(t);var i=n.plugin.cipher,s=n.plugin.increment,o=n.plugin.formatKey,a=n.plugin.formatSeed,f=e.util.createBuffer();l()},n.generateSync=function(t){var r=n.plugin.cipher,i=n.plugin.increment,s=n.plugin.formatKey,o=n.plugin.formatSeed,u=e.util.createBuffer();while(u.length()=1048576){var f=+(new Date);if(n.time===null||f-n.time>100)n.key=null}n.key===null&&a();var l=r(n.key,n.seed);n.generated+=l.length,u.putBytes(l),n.key=s(r(n.key,i(n.seed))),n.seed=o(r(n.key,n.seed))}return u.getBytes(t)},r?(n.seedFile=function(e,t){r.randomBytes(e,function(e,n){if(e)return t(e);t(null,n.toString())})},n.seedFileSync=function(e){return r.randomBytes(e).toString()}):(n.seedFile=function(e,t){try{t(null,l(e))}catch(n){t(n)}},n.seedFileSync=l),n.collect=function(e){var t=e.length;for(var r=0;r>i&255);n.collect(r)},n.registerWorker=function(e){if(e===self)n.seedFile=function(e,t){function n(e){var r=e.data;r.forge&&r.forge.prng&&(self.removeEventListener("message",n),t(r.forge.prng.err,r.forge.prng.bytes))}self.addEventListener("message",n),self.postMessage({forge:{prng:{needed:e}}})};else{function t(t){var r=t.data;r.forge&&r.forge.prng&&n.seedFile(r.forge.prng.needed,function(t,n){e.postMessage({forge:{prng:{err:t,bytes:n}}})})}e.addEventListener("message",t)}},n}}var r="prng";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o>16-t},i=function(e,t){return(e&65535)>>t|e<<16-t&65535};e.rc2=e.rc2||{},e.rc2.expandKey=function(n,r){typeof n=="string"&&(n=e.util.createBuffer(n)),r=r||128;var i=n,s=n.length(),o=r,u=Math.ceil(o/8),a=255>>(o&7),f;for(f=s;f<128;f++)i.putByte(t[i.at(f-1)+i.at(f-s)&255]);i.setAt(128-u,t[i.at(128-u)&a]);for(f=127-u;f>=0;f--)i.setAt(f,t[i.at(f+1)^i.at(f+u)]);return i};var s=function(t,s,o){var u=!1,a=null,f=null,l=null,c,h,p,d,v=[];t=e.rc2.expandKey(t,s);for(p=0;p<64;p++)v.push(t.getInt16Le());o?(c=function(e){for(p=0;p<4;p++)e[p]+=v[d]+(e[(p+3)%4]&e[(p+2)%4])+(~e[(p+3)%4]&e[(p+1)%4]),e[p]=r(e[p],n[p]),d++},h=function(e){for(p=0;p<4;p++)e[p]+=v[e[(p+3)%4]&63]}):(c=function(e){for(p=3;p>=0;p--)e[p]=i(e[p],n[p]),e[p]-=v[d]+(e[(p+3)%4]&e[(p+2)%4])+(~e[(p+3)%4]&e[(p+1)%4]),d--},h=function(e){for(p=3;p>=0;p--)e[p]-=v[e[(p+3)%4]&63]});var m=function(e){var t=[];for(p=0;p<4;p++){var n=a.getInt16Le();l!==null&&(o?n^=l.getInt16Le():l.putInt16Le(n)),t.push(n&65535)}d=o?0:63;for(var r=0;r=8)m([[5,c],[1,h],[6,c],[1,h],[5,c]])},finish:function(e){var t=!0;if(o)if(e)t=e(8,a,!o);else{var n=a.length()===8?8:8-a.length();a.fillWithByte(n,n)}t&&(u=!0,g.update());if(!o){t=a.length()===0;if(t)if(e)t=e(8,f,!o);else{var r=f.length(),i=f.at(r-1);i>r?t=!1:f.truncate(i)}}return t}},g};e.rc2.startEncrypting=function(t,n,r){var i=e.rc2.createEncryptionCipher(t,128);return i.start(n,r),i},e.rc2.createEncryptionCipher=function(e,t){return s(e,t,!0)},e.rc2.startDecrypting=function(t,n,r){var i=e.rc2.createDecryptionCipher(t,128);return i.start(n,r),i},e.rc2.createDecryptionCipher=function(e,t){return s(e,t,!1)}}var r="rc2";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=0){var o=t*this.data[e++]+n.data[r]+i;i=Math.floor(o/67108864),n.data[r++]=o&67108863}return i}function u(e,t,n,r,i,s){var o=t&32767,u=t>>15;while(--s>=0){var a=this.data[e]&32767,f=this.data[e++]>>15,l=u*a+f*o;a=o*a+((l&32767)<<15)+n.data[r]+(i&1073741823),i=(a>>>30)+(l>>>15)+u*f+(i>>>30),n.data[r++]=a&1073741823}return i}function a(e,t,n,r,i,s){var o=t&16383,u=t>>14;while(--s>=0){var a=this.data[e]&16383,f=this.data[e++]>>14,l=u*a+f*o;a=o*a+((l&16383)<<14)+n.data[r]+i,i=(a>>28)+(l>>14)+u*f,n.data[r++]=a&268435455}return i}function d(e){return l.charAt(e)}function v(e,t){var n=c[e.charCodeAt(t)];return n==null?-1:n}function m(e){for(var t=this.t-1;t>=0;--t)e.data[t]=this.data[t];e.t=this.t,e.s=this.s}function g(e){this.t=1,this.s=e<0?-1:0,e>0?this.data[0]=e:e<-1?this.data[0]=e+this.DV:this.t=0}function y(e){var t=s();return t.fromInt(e),t}function b(e,t){var n;if(t==16)n=4;else if(t==8)n=3;else if(t==256)n=8;else if(t==2)n=1;else if(t==32)n=5;else{if(t!=4){this.fromRadix(e,t);return}n=2}this.t=0,this.s=0;var r=e.length,s=!1,o=0;while(--r>=0){var u=n==8?e[r]&255:v(e,r);if(u<0){e.charAt(r)=="-"&&(s=!0);continue}s=!1,o==0?this.data[this.t++]=u:o+n>this.DB?(this.data[this.t-1]|=(u&(1<>this.DB-o):this.data[this.t-1]|=u<=this.DB&&(o-=this.DB)}n==8&&(e[0]&128)!=0&&(this.s=-1,o>0&&(this.data[this.t-1]|=(1<0&&this.data[this.t-1]==e)--this.t}function E(e){if(this.s<0)return"-"+this.negate().toString(e);var t;if(e==16)t=4;else if(e==8)t=3;else if(e==2)t=1;else if(e==32)t=5;else{if(e!=4)return this.toRadix(e);t=2}var n=(1<0){u>u)>0&&(i=!0,s=d(r));while(o>=0)u>(u+=this.DB-t)):(r=this.data[o]>>(u-=t)&n,u<=0&&(u+=this.DB,--o)),r>0&&(i=!0),i&&(s+=d(r))}return i?s:"0"}function S(){var e=s();return i.ZERO.subTo(this,e),e}function x(){return this.s<0?this.negate():this}function T(e){var t=this.s-e.s;if(t!=0)return t;var n=this.t;t=n-e.t;if(t!=0)return this.s<0?-t:t;while(--n>=0)if((t=this.data[n]-e.data[n])!=0)return t;return 0}function N(e){var t=1,n;return(n=e>>>16)!=0&&(e=n,t+=16),(n=e>>8)!=0&&(e=n,t+=8),(n=e>>4)!=0&&(e=n,t+=4),(n=e>>2)!=0&&(e=n,t+=2),(n=e>>1)!=0&&(e=n,t+=1),t}function C(){return this.t<=0?0:this.DB*(this.t-1)+N(this.data[this.t-1]^this.s&this.DM)}function k(e,t){var n;for(n=this.t-1;n>=0;--n)t.data[n+e]=this.data[n];for(n=e-1;n>=0;--n)t.data[n]=0;t.t=this.t+e,t.s=this.s}function L(e,t){for(var n=e;n=0;--u)t.data[u+s+1]=this.data[u]>>r|o,o=(this.data[u]&i)<=0;--u)t.data[u]=0;t.data[s]=o,t.t=this.t+s+1,t.s=this.s,t.clamp()}function O(e,t){t.s=this.s;var n=Math.floor(e/this.DB);if(n>=this.t){t.t=0;return}var r=e%this.DB,i=this.DB-r,s=(1<>r;for(var o=n+1;o>r;r>0&&(t.data[this.t-n-1]|=(this.s&s)<>=this.DB;if(e.t>=this.DB;r+=this.s}else{r+=this.s;while(n>=this.DB;r-=e.s}t.s=r<0?-1:0,r<-1?t.data[n++]=this.DV+r:r>0&&(t.data[n++]=r),t.t=n,t.clamp()}function _(e,t){var n=this.abs(),r=e.abs(),s=n.t;t.t=s+r.t;while(--s>=0)t.data[s]=0;for(s=0;s=0)e.data[n]=0;for(n=0;n=t.DV&&(e.data[n+t.t]-=t.DV,e.data[n+t.t+1]=1)}e.t>0&&(e.data[e.t-1]+=t.am(n,t.data[n],e,2*n,0,1)),e.s=0,e.clamp()}function P(e,t,n){var r=e.abs();if(r.t<=0)return;var o=this.abs();if(o.t0?(r.lShiftTo(l,u),o.lShiftTo(l,n)):(r.copyTo(u),o.copyTo(n));var c=u.t,h=u.data[c-1];if(h==0)return;var p=h*(1<1?u.data[c-2]>>this.F2:0),d=this.FV/p,v=(1<=0&&(n.data[n.t++]=1,n.subTo(b,n)),i.ONE.dlShiftTo(c,b),b.subTo(u,u);while(u.t=0){var w=n.data[--g]==h?this.DM:Math.floor(n.data[g]*d+(n.data[g-1]+m)*v);if((n.data[g]+=u.am(0,w,n,y,0,c))0&&n.rShiftTo(l,n),a<0&&i.ZERO.subTo(n,n)}function H(e){var t=s();return this.abs().divRemTo(e,null,t),this.s<0&&t.compareTo(i.ZERO)>0&&e.subTo(t,t),t}function B(e){this.m=e}function j(e){return e.s<0||e.compareTo(this.m)>=0?e.mod(this.m):e}function F(e){return e}function I(e){e.divRemTo(this.m,null,e)}function q(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function R(e,t){e.squareTo(t),this.reduce(t)}function U(){if(this.t<1)return 0;var e=this.data[0];if((e&1)==0)return 0;var t=e&3;return t=t*(2-(e&15)*t)&15,t=t*(2-(e&255)*t)&255,t=t*(2-((e&65535)*t&65535))&65535,t=t*(2-e*t%this.DV)%this.DV,t>0?this.DV-t:-t}function z(e){this.m=e,this.mp=e.invDigit(),this.mpl=this.mp&32767,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(t,t),t}function X(e){var t=s();return e.copyTo(t),this.reduce(t),t}function V(e){while(e.t<=this.mt2)e.data[e.t++]=0;for(var t=0;t>15)*this.mpl&this.um)<<15)&e.DM;n=t+this.m.t,e.data[n]+=this.m.am(0,r,e,t,0,this.m.t);while(e.data[n]>=e.DV)e.data[n]-=e.DV,e.data[++n]++}e.clamp(),e.drShiftTo(this.m.t,e),e.compareTo(this.m)>=0&&e.subTo(this.m,e)}function $(e,t){e.squareTo(t),this.reduce(t)}function J(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function K(){return(this.t>0?this.data[0]&1:this.s)==0}function Q(e,t){if(e>4294967295||e<1)return i.ONE;var n=s(),r=s(),o=t.convert(this),u=N(e)-1;o.copyTo(n);while(--u>=0){t.sqrTo(n,r);if((e&1<0)t.mulTo(r,o,n);else{var a=n;n=r,r=a}}return t.revert(n)}function G(e,t){var n;return e<256||t.isEven()?n=new B(t):n=new z(t),this.exp(e,n)}function Y(){var e=s();return this.copyTo(e),e}function Z(){if(this.s<0){if(this.t==1)return this.data[0]-this.DV;if(this.t==0)return-1}else{if(this.t==1)return this.data[0];if(this.t==0)return 0}return(this.data[1]&(1<<32-this.DB)-1)<>24}function tt(){return this.t==0?this.s:this.data[0]<<16>>16}function nt(e){return Math.floor(Math.LN2*this.DB/Math.log(e))}function rt(){return this.s<0?-1:this.t<=0||this.t==1&&this.data[0]<=0?0:1}function it(e){e==null&&(e=10);if(this.signum()==0||e<2||e>36)return"0";var t=this.chunkSize(e),n=Math.pow(e,t),r=y(n),i=s(),o=s(),u="";this.divRemTo(r,i,o);while(i.signum()>0)u=(n+o.intValue()).toString(e).substr(1)+u,i.divRemTo(r,i,o);return o.intValue().toString(e)+u}function st(e,t){this.fromInt(0),t==null&&(t=10);var n=this.chunkSize(t),r=Math.pow(t,n),s=!1,o=0,u=0;for(var a=0;a=n&&(this.dMultiply(r),this.dAddOffset(u,0),o=0,u=0)}o>0&&(this.dMultiply(Math.pow(t,o)),this.dAddOffset(u,0)),s&&i.ZERO.subTo(this,this)}function ot(e,t,n){if("number"==typeof t)if(e<2)this.fromInt(1);else{this.fromNumber(e,n),this.testBit(e-1)||this.bitwiseTo(i.ONE.shiftLeft(e-1),dt,this),this.isEven()&&this.dAddOffset(1,0);while(!this.isProbablePrime(t))this.dAddOffset(2,0),this.bitLength()>e&&this.subTo(i.ONE.shiftLeft(e-1),this)}else{var r=new Array,s=e&7;r.length=(e>>3)+1,t.nextBytes(r),s>0?r[0]&=(1<0){n>n)!=(this.s&this.DM)>>n&&(t[i++]=r|this.s<=0){n<8?(r=(this.data[e]&(1<>(n+=this.DB-8)):(r=this.data[e]>>(n-=8)&255,n<=0&&(n+=this.DB,--e)),(r&128)!=0&&(r|=-256),i==0&&(this.s&128)!=(r&128)&&++i;if(i>0||r!=this.s)t[i++]=r}}return t}function at(e){return this.compareTo(e)==0}function ft(e){return this.compareTo(e)<0?this:e}function lt(e){return this.compareTo(e)>0?this:e}function ct(e,t,n){var r,i,s=Math.min(e.t,this.t);for(r=0;r>=16,t+=16),(e&255)==0&&(e>>=8,t+=8),(e&15)==0&&(e>>=4,t+=4),(e&3)==0&&(e>>=2,t+=2),(e&1)==0&&++t,t}function Tt(){for(var e=0;e=this.t?this.s!=0:(this.data[t]&1<>=this.DB;if(e.t>=this.DB;r+=this.s}else{r+=this.s;while(n>=this.DB;r+=e.s}t.s=r<0?-1:0,r>0?t.data[n++]=r:r<-1&&(t.data[n++]=this.DV+r),t.t=n,t.clamp()}function Dt(e){var t=s();return this.addTo(e,t),t}function Pt(e){var t=s();return this.subTo(e,t),t}function Ht(e){var t=s();return this.multiplyTo(e,t),t}function Bt(e){var t=s();return this.divRemTo(e,t,null),t}function jt(e){var t=s();return this.divRemTo(e,null,t),t}function Ft(e){var t=s(),n=s();return this.divRemTo(e,t,n),new Array(t,n)}function It(e){this.data[this.t]=this.am(0,e-1,this,0,0,this.t),++this.t,this.clamp()}function qt(e,t){if(e==0)return;while(this.t<=t)this.data[this.t++]=0;this.data[t]+=e;while(this.data[t]>=this.DV)this.data[t]-=this.DV,++t>=this.t&&(this.data[this.t++]=0),++this.data[t]}function Rt(){}function Ut(e){return e}function zt(e,t,n){e.multiplyTo(t,n)}function Wt(e,t){e.squareTo(t)}function Xt(e){return this.exp(e,new Rt)}function Vt(e,t,n){var r=Math.min(this.t+e.t,t);n.s=0,n.t=r;while(r>0)n.data[--r]=0;var i;for(i=n.t-this.t;r=0)n.data[r]=0;for(r=Math.max(t-this.t,0);r2*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=s();return e.copyTo(t),this.reduce(t),t}function Qt(e){return e}function Gt(e){e.drShiftTo(this.m.t-1,this.r2),e.t>this.m.t+1&&(e.t=this.m.t+1,e.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);while(e.compareTo(this.r2)<0)e.dAddOffset(1,this.m.t+1);e.subTo(this.r2,e);while(e.compareTo(this.m)>=0)e.subTo(this.m,e)}function Yt(e,t){e.squareTo(t),this.reduce(t)}function Zt(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function en(e,t){var n=e.bitLength(),r,i=y(1),o;if(n<=0)return i;n<18?r=1:n<48?r=3:n<144?r=4:n<768?r=5:r=6,n<8?o=new B(t):t.isEven()?o=new Jt(t):o=new z(t);var u=new Array,a=3,f=r-1,l=(1<1){var c=s();o.sqrTo(u[1],c);while(a<=l)u[a]=s(),o.mulTo(c,u[a-2],u[a]),a+=2}var h=e.t-1,p,d=!0,v=s(),m;n=N(e.data[h])-1;while(h>=0){n>=f?p=e.data[h]>>n-f&l:(p=(e.data[h]&(1<0&&(p|=e.data[h-1]>>this.DB+n-f)),a=r;while((p&1)==0)p>>=1,--a;(n-=a)<0&&(n+=this.DB,--h);if(d)u[p].copyTo(i),d=!1;else{while(a>1)o.sqrTo(i,v),o.sqrTo(v,i),a-=2;a>0?o.sqrTo(i,v):(m=i,i=v,v=m),o.mulTo(v,u[p],i)}while(h>=0&&(e.data[h]&1<0&&(t.rShiftTo(s,t),n.rShiftTo(s,n));while(t.signum()>0)(i=t.getLowestSetBit())>0&&t.rShiftTo(i,t),(i=n.getLowestSetBit())>0&&n.rShiftTo(i,n),t.compareTo(n)>=0?(t.subTo(n,t),t.rShiftTo(1,t)):(n.subTo(t,n),n.rShiftTo(1,n));return s>0&&n.lShiftTo(s,n),n}function nn(e){if(e<=0)return 0;var t=this.DV%e,n=this.s<0?e-1:0;if(this.t>0)if(t==0)n=this.data[0]%e;else for(var r=this.t-1;r>=0;--r)n=(t*n+this.data[r])%e;return n}function rn(e){var t=e.isEven();if(this.isEven()&&t||e.signum()==0)return i.ZERO;var n=e.clone(),r=this.clone(),s=y(1),o=y(0),u=y(0),a=y(1);while(n.signum()!=0){while(n.isEven()){n.rShiftTo(1,n);if(t){if(!s.isEven()||!o.isEven())s.addTo(this,s),o.subTo(e,o);s.rShiftTo(1,s)}else o.isEven()||o.subTo(e,o);o.rShiftTo(1,o)}while(r.isEven()){r.rShiftTo(1,r);if(t){if(!u.isEven()||!a.isEven())u.addTo(this,u),a.subTo(e,a);u.rShiftTo(1,u)}else a.isEven()||a.subTo(e,a);a.rShiftTo(1,a)}n.compareTo(r)>=0?(n.subTo(r,n),t&&s.subTo(u,s),o.subTo(a,o)):(r.subTo(n,r),t&&u.subTo(s,u),a.subTo(o,a))}return r.compareTo(i.ONE)!=0?i.ZERO:a.compareTo(e)>=0?a.subtract(e):a.signum()<0?(a.addTo(e,a),a.signum()<0?a.add(e):a):a}function un(e){var t,n=this.abs();if(n.t==1&&n.data[0]<=sn[sn.length-1]){for(t=0;t=0);var a=o.modPow(r,this);if(a.compareTo(i.ONE)!=0&&a.compareTo(t)!=0){var f=1;while(f++>24&255,o>>16&255,o>>8&255,o&255);r.start(),r.update(t+u),i+=r.digest().getBytes()}return i.substring(0,n)}var t=e.pkcs1=e.pkcs1||{};t.encode_rsa_oaep=function(t,r,i){var s=undefined,o=undefined,u=undefined,a=undefined;typeof i=="string"?(s=i,o=arguments[3]||undefined,u=arguments[4]||undefined):i&&(s=i.label||undefined,o=i.seed||undefined,u=i.md||undefined,i.mgf1&&i.mgf1.md&&(a=i.mgf1.md)),u?u.start():u=e.md.sha1.create(),a||(a=u);var f=Math.ceil(t.n.bitLength()/8),l=f-2*u.digestLength-2;if(r.length>l)throw{message:"RSAES-OAEP input message length is too long.",length:r.length,maxLength:l};s||(s=""),u.update(s,"raw");var c=u.digest(),h="",p=l-r.length;for(var d=0;ds-11)throw{message:"Message is too long for PKCS#1 v1.5 padding.",length:t.length,max:s-11};i.putByte(0),i.putByte(r);var o=s-3-t.length,u;if(r===0||r===1){u=r===0?0:255;for(var a=0;a0){var f=0,l=e.random.getBytes(o);for(var a=0;a1){if(o.getByte()!==255){--o.read;break}++f}}else if(a===2){f=0;while(o.length()>1){if(o.getByte()===0){--o.read;break}++f}}var c=o.getByte();if(c!==0||f!==s-3-o.length())throw{message:"Encryption block is invalid."};return o.getBytes()}function p(n,i,s){function p(){u=Math.max(1,u),d(n.pBits,function(e,t){if(e)return s(e);n.p=t,d(n.qBits,v)})}function d(e,r){function d(){var r=e-1,i=new t(e,n.rng);return i.testBit(r)||i.bitwiseTo(t.ONE.shiftLeft(r),h,i),i.dAddOffset(31-i.mod(c).byteValue(),0),i}function m(s){if(v)return;--o;var u=s.data;if(u.found){for(var l=0;le&&(p=d());var c=p.toString(16);s.target.postMessage({e:n.eInt,hex:c,workLoad:a}),p.dAddOffset(f,0)}var i=[];for(var s=0;s="8"&&(n="00"+n),e.util.hexToBytes(n)}function v(e){return e<=100?27:e<=150?18:e<=200?15:e<=250?12:e<=300?9:e<=350?8:e<=400?7:e<=500?6:e<=600?5:e<=800?4:e<=1250?3:2}if(typeof t=="undefined")var t=e.jsbn.BigInteger;var n=e.asn1;e.pki=e.pki||{},e.pki.rsa=e.rsa=e.rsa||{};var r=e.pki,i=[6,4,2,4,2,4,6,2],s={name:"PrivateKeyInfo",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"PrivateKeyInfo.version",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"PrivateKeyInfo.privateKeyAlgorithm",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:n.Class.UNIVERSAL,type:n.Type.OID,constructed:!1,capture:"privateKeyOid"}]},{name:"PrivateKeyInfo",tagClass:n.Class.UNIVERSAL,type:n.Type.OCTETSTRING,constructed:!1,capture:"privateKey"}]},o={name:"RSAPrivateKey",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPrivateKey.version",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"RSAPrivateKey.modulus",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyModulus"},{name:"RSAPrivateKey.publicExponent",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyPublicExponent"},{name:"RSAPrivateKey.privateExponent",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyPrivateExponent"},{name:"RSAPrivateKey.prime1",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyPrime1"},{name:"RSAPrivateKey.prime2",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyPrime2"},{name:"RSAPrivateKey.exponent1",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyExponent1"},{name:"RSAPrivateKey.exponent2",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyExponent2"},{name:"RSAPrivateKey.coefficient",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyCoefficient"}]},u={name:"RSAPublicKey",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPublicKey.modulus",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"publicKeyModulus"},{name:"RSAPublicKey.exponent",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"publicKeyExponent"}]},a=e.pki.rsa.publicKeyValidator={name:"SubjectPublicKeyInfo",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,captureAsn1:"subjectPublicKeyInfo",value:[{name:"SubjectPublicKeyInfo.AlgorithmIdentifier",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:n.Class.UNIVERSAL,type:n.Type.OID,constructed:!1,capture:"publicKeyOid"}]},{name:"SubjectPublicKeyInfo.subjectPublicKey",tagClass:n.Class.UNIVERSAL,type:n.Type.BITSTRING,constructed:!1,value:[{name:"SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,optional:!0,captureAsn1:"rsaPublicKey"}]}]},f=function(e){var t;if(e.algorithm in r.oids){t=r.oids[e.algorithm];var i=n.oidToDer(t).getBytes(),s=n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[]),o=n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[]);o.value.push(n.create(n.Class.UNIVERSAL,n.Type.OID,!1,i)),o.value.push(n.create(n.Class.UNIVERSAL,n.Type.NULL,!1,""));var u=n.create(n.Class.UNIVERSAL,n.Type.OCTETSTRING,!1,e.digest().getBytes());return s.value.push(o),s.value.push(u),n.toDer(s).getBytes()}throw{message:"Unknown message digest algorithm.",algorithm:e.algorithm}},l=function(e,n,r){var i;if(r)i=e.modPow(n.e,n.n);else if(!n.p||!n.q)i=e.modPow(n.d,n.n);else{n.dP||(n.dP=n.d.mod(n.p.subtract(t.ONE))),n.dQ||(n.dQ=n.d.mod(n.q.subtract(t.ONE))),n.qInv||(n.qInv=n.q.modInverse(n.p));var s=e.mod(n.p).modPow(n.dP,n.p),o=e.mod(n.q).modPow(n.dQ,n.q);while(s.compareTo(o)<0)s=s.add(n.p);i=s.subtract(o).multiply(n.qInv).mod(n.p).multiply(n.q).add(o)}return i};r.rsa.encrypt=function(n,r,i){var s=i,o,u=Math.ceil(r.n.bitLength()/8);i!==!1&&i!==!0?(s=i===2,o=c(n,r,i)):(o=e.util.createBuffer(),o.putBytes(n));var a=new t(o.toHex(),16),f=l(a,r,s),h=f.toString(16),p=e.util.createBuffer(),d=u-Math.ceil(h.length/2);while(d>0)p.putByte(0),--d;return p.putBytes(e.util.hexToBytes(h)),p.getBytes()},r.rsa.decrypt=function(n,r,i,s){var o=Math.ceil(r.n.bitLength()/8);if(n.length!==o)throw{message:"Encrypted message length is invalid.",length:n.length,expected:o};var u=new t(e.util.createBuffer(n).toHex(),16);if(u.compareTo(r.n)>=0)throw{message:"Encrypted message is invalid."};var a=l(u,r,i),f=a.toString(16),c=e.util.createBuffer(),p=o-Math.ceil(f.length/2);while(p>0)c.putByte(0),--p;return c.putBytes(e.util.hexToBytes(f)),s!==!1?h(c.getBytes(),r,i):c.getBytes()},r.rsa.createKeyPairGenerationState=function(n,r){typeof n=="string"&&(n=parseInt(n,10)),n=n||2048;var i={nextBytes:function(t){var n=e.random.getBytes(t.length);for(var r=0;r>1,pBits:n-(n>>1),pqState:0,num:null,keys:null};return s.e.fromInt(s.eInt),s},r.rsa.stepKeyPairGenerationState=function(e,n){var s=new t(null);s.fromInt(30);var o=0,u=function(e,t){return e|t},a=+(new Date),f,l=0;while(e.keys===null&&(n<=0||lc?e.pqState=0:e.num.isProbablePrime(v(e.num.bitLength()))?++e.pqState:e.num.dAddOffset(i[o++%8],0):e.pqState===2?e.pqState=e.num.subtract(t.ONE).gcd(e.e).compareTo(t.ONE)===0?3:0:e.pqState===3&&(e.pqState=0,e.p===null?e.p=e.num:e.q=e.num,e.p!==null&&e.q!==null&&++e.state,e.num=null)}else if(e.state===1)e.p.compareTo(e.q)<0&&(e.num=e.p,e.p=e.q,e.q=e.num),++e.state;else if(e.state===2)e.p1=e.p.subtract(t.ONE),e.q1=e.q.subtract(t.ONE),e.phi=e.p1.multiply(e.q1),++e.state;else if(e.state===3)e.phi.gcd(e.e).compareTo(t.ONE)===0?++e.state:(e.p=null,e.q=null,e.state=0);else if(e.state===4)e.n=e.p.multiply(e.q),e.n.bitLength()===e.bits?++e.state:(e.q=null,e.state=0);else if(e.state===5){var p=e.e.modInverse(e.phi);e.keys={privateKey:r.rsa.setPrivateKey(e.n,e.e,p,e.p,e.q,p.mod(e.p1),p.mod(e.q1),e.q.modInverse(e.p)),publicKey:r.rsa.setPublicKey(e.n,e.e)}}f=+(new Date),l+=f-a,a=f}return e.keys!==null},r.rsa.generateKeyPair=function(e,t,n,i){arguments.length===1?typeof e=="object"?(n=e,e=undefined):typeof e=="function"&&(i=e,e=undefined):arguments.length===2?(typeof e=="number"?typeof t=="function"?i=t:n=t:(n=e,i=t,e=undefined),t=undefined):arguments.length===3&&(typeof t=="number"?typeof n=="function"&&(i=n,n=undefined):(i=n,n=t,t=undefined)),n=n||{},e===undefined&&(e=n.bits||2048),t===undefined&&(t=n.e||65537);var s=r.rsa.createKeyPairGenerationState(e,t);if(!i)return r.rsa.stepKeyPairGenerationState(s,0),s.keys;p(s,n,i)},r.setRsaPublicKey=r.rsa.setPublicKey=function(t,i){var s={n:t,e:i};return s.encrypt=function(t,n,i){typeof n=="string"?n=n.toUpperCase():n===undefined&&(n="RSAES-PKCS1-V1_5");if(n==="RSAES-PKCS1-V1_5")n={encode:function(e,t,n){return c(e,t,2).getBytes()}};else if(n==="RSA-OAEP"||n==="RSAES-OAEP")n={encode:function(t,n){return e.pkcs1.encode_rsa_oaep(n,t,i)}};else{if(["RAW","NONE","NULL",null].indexOf(n)===-1)throw{message:'Unsupported encryption scheme: "'+n+'".'};n={encode:function(e){return e}}}var o=n.encode(t,s,!0);return r.rsa.encrypt(o,s,!0)},s.verify=function(e,t,i){typeof i=="string"?i=i.toUpperCase():i===undefined&&(i="RSASSA-PKCS1-V1_5");if(i==="RSASSA-PKCS1-V1_5")i={verify:function(e,t){t=h(t,s,!0);var r=n.fromDer(t);return e===r.value[1].value}};else if(i==="NONE"||i==="NULL"||i===null)i={verify:function(e,t){return t=h(t,s,!0),e===t}};var o=r.rsa.decrypt(t,s,!0,!1);return i.verify(e,o,s.n.bitLength())},s},r.setRsaPrivateKey=r.rsa.setPrivateKey=function(t,n,i,s,o,u,a,l){var c={n:t,e:n,d:i,p:s,q:o,dP:u,dQ:a,qInv:l};return c.decrypt=function(t,n,i){typeof n=="string"?n=n.toUpperCase():n===undefined&&(n="RSAES-PKCS1-V1_5");var s=r.rsa.decrypt(t,c,!1,!1);if(n==="RSAES-PKCS1-V1_5")n={decode:h};else if(n==="RSA-OAEP"||n==="RSAES-OAEP")n={decode:function(t,n){return e.pkcs1.decode_rsa_oaep(n,t,i)}};else{if(["RAW","NONE","NULL",null].indexOf(n)===-1)throw{message:'Unsupported encryption scheme: "'+n+'".'};n={decode:function(e){return e}}}return n.decode(s,c,!1)},c.sign=function(e,t){var n=!1;typeof t=="string"&&(t=t.toUpperCase());if(t===undefined||t==="RSASSA-PKCS1-V1_5")t={encode:f},n=1;else if(t==="NONE"||t==="NULL"||t===null)t={encode:function(){return e}},n=1;var i=t.encode(e,c.n.bitLength());return r.rsa.encrypt(i,c,n)},c},r.wrapRsaPrivateKey=function(e){return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,n.integerToDer(0).getBytes()),n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.OID,!1,n.oidToDer(r.oids.rsaEncryption).getBytes()),n.create(n.Class.UNIVERSAL,n.Type.NULL,!1,"")]),n.create(n.Class.UNIVERSAL,n.Type.OCTETSTRING,!1,n.toDer(e).getBytes())])},r.privateKeyFromAsn1=function(i){var u={},a=[];n.validate(i,s,u,a)&&(i=n.fromDer(e.util.createBuffer(u.privateKey))),u={},a=[];if(!n.validate(i,o,u,a))throw{message:"Cannot read private key. ASN.1 object does not contain an RSAPrivateKey.",errors:a};var f,l,c,h,p,d,v,m;return f=e.util.createBuffer(u.privateKeyModulus).toHex(),l=e.util.createBuffer(u.privateKeyPublicExponent).toHex(),c=e.util.createBuffer(u.privateKeyPrivateExponent).toHex(),h=e.util.createBuffer(u.privateKeyPrime1).toHex(),p=e.util.createBuffer(u.privateKeyPrime2).toHex(),d=e.util.createBuffer(u.privateKeyExponent1).toHex(),v=e.util.createBuffer(u.privateKeyExponent2).toHex(),m=e.util.createBuffer(u.privateKeyCoefficient).toHex(),r.setRsaPrivateKey(new t(f,16),new t(l,16),new t(c,16),new t(h,16),new t(p,16),new t(d,16),new t(v,16),new t(m,16))},r.privateKeyToAsn1=r.privateKeyToRSAPrivateKey=function(e){return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,n.integerToDer(0).getBytes()),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.n)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.e)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.d)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.p)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.q)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.dP)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.dQ)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.qInv))])},r.publicKeyFromAsn1=function(i){var s={},o=[];if(n.validate(i,a,s,o)){var f=n.derToOid(s.publicKeyOid);if(f!==r.oids.rsaEncryption)throw{message:"Cannot read public key. Unknown OID.",oid:f};i=s.rsaPublicKey}o=[];if(!n.validate(i,u,s,o))throw{message:"Cannot read public key. ASN.1 object does not contain an RSAPublicKey.",errors:o};var l=e.util.createBuffer(s.publicKeyModulus).toHex(),c=e.util.createBuffer(s.publicKeyExponent).toHex();return r.setRsaPublicKey(new t(l,16),new t(c,16))},r.publicKeyToAsn1=r.publicKeyToSubjectPublicKeyInfo=function(e){return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.OID,!1,n.oidToDer(r.oids.rsaEncryption).getBytes()),n.create(n.Class.UNIVERSAL,n.Type.NULL,!1,"")]),n.create(n.Class.UNIVERSAL,n.Type.BITSTRING,!1,[r.publicKeyToRSAPublicKey(e)])])},r.publicKeyToRSAPublicKey=function(e){return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.n)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.e))])}}var r="rsa";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=0;a--)A>>=8,A+=N.at(a)+L.at(a),L.setAt(a,A&255);k.putBuffer(L)}w=k,c.putBuffer(x)}return c.truncate(c.length()-s),c},r.pbe.getCipher=function(e,t,n){switch(e){case r.oids.pkcs5PBES2:return r.pbe.getCipherForPBES2(e,t,n);case r.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:case r.oids["pbewithSHAAnd40BitRC2-CBC"]:return r.pbe.getCipherForPKCS12PBE(e,t,n);default:throw{message:"Cannot read encrypted PBE data block. Unsupported OID.",oid:e,supportedOids:["pkcs5PBES2","pbeWithSHAAnd3-KeyTripleDES-CBC","pbewithSHAAnd40BitRC2-CBC"]}}},r.pbe.getCipherForPBES2=function(t,i,s){var u={},a=[];if(!n.validate(i,o,u,a))throw{message:"Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.",errors:a};t=n.derToOid(u.kdfOid);if(t!==r.oids.pkcs5PBKDF2)throw{message:"Cannot read encrypted private key. Unsupported key derivation function OID.",oid:t,supportedOids:["pkcs5PBKDF2"]};t=n.derToOid(u.encOid);if(t!==r.oids["aes128-CBC"]&&t!==r.oids["aes192-CBC"]&&t!==r.oids["aes256-CBC"]&&t!==r.oids["des-EDE3-CBC"]&&t!==r.oids.desCBC)throw{message:"Cannot read encrypted private key. Unsupported encryption scheme OID.",oid:t,supportedOids:["aes128-CBC","aes192-CBC","aes256-CBC","des-EDE3-CBC","desCBC"]};var f=u.kdfSalt,l=e.util.createBuffer(u.kdfIterationCount);l=l.getInt(l.length()<<3);var c,h;switch(r.oids[t]){case"aes128-CBC":c=16,h=e.aes.createDecryptionCipher;break;case"aes192-CBC":c=24,h=e.aes.createDecryptionCipher;break;case"aes256-CBC":c=32,h=e.aes.createDecryptionCipher;break;case"des-EDE3-CBC":c=24,h=e.des.createDecryptionCipher;break;case"desCBC":c=8,h=e.des.createDecryptionCipher}var p=e.pkcs5.pbkdf2(s,f,l,c),d=u.encIv,v=h(p);return v.start(d),v},r.pbe.getCipherForPKCS12PBE=function(t,i,s){var o={},a=[];if(!n.validate(i,u,o,a))throw{message:"Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.",errors:a};var f=e.util.createBuffer(o.salt),l=e.util.createBuffer(o.iterations);l=l.getInt(l.length()<<3);var c,h,p;switch(t){case r.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:c=24,h=8,p=e.des.startDecrypting;break;case r.oids["pbewithSHAAnd40BitRC2-CBC"]:c=5,h=8,p=function(t,n){var r=e.rc2.createDecryptionCipher(t,40);return r.start(n,null),r};break;default:throw{message:"Cannot read PKCS #12 PBE data block. Unsupported OID.",oid:t}}var d=r.pbe.generatePkcs12Key(s,f,1,l,c),v=r.pbe.generatePkcs12Key(s,f,2,l,h);return p(d,v)}}var r="pbe";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o>8*l-f&255;if((h.charCodeAt(0)&d)!==0)throw{message:"Bits beyond keysize not zero as expected."};var v=n.generate(p,c),m="";for(a=0;a>8*f-a&255;return y=String.fromCharCode(y.charCodeAt(0)&~b)+y.substr(1),y+p+String.fromCharCode(188)},s}}var r="pss";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o1&&(c=l.value.charCodeAt(1),h=l.value.length>2?l.value.charCodeAt(2):0),s.digitalSignature=(c&128)===128,s.nonRepudiation=(c&64)===64,s.keyEncipherment=(c&32)===32,s.dataEncipherment=(c&16)===16,s.keyAgreement=(c&8)===8,s.keyCertSign=(c&4)===4,s.cRLSign=(c&2)===2,s.encipherOnly=(c&1)===1,s.decipherOnly=(h&128)===128}else if(s.name==="basicConstraints"){var l=t.fromDer(s.value);l.value.length>0&&l.value[0].type===t.Type.BOOLEAN?s.cA=l.value[0].value.charCodeAt(0)!==0:s.cA=!1;var p=null;l.value.length>0&&l.value[0].type===t.Type.INTEGER?p=l.value[0].value:l.value.length>1&&(p=l.value[1].value),p!==null&&(s.pathLenConstraint=t.derToInteger(p))}else if(s.name==="extKeyUsage"){var l=t.fromDer(s.value);for(var d=0;d1&&(c=l.value.charCodeAt(1)),s.client=(c&128)===128,s.server=(c&64)===64,s.email=(c&32)===32,s.objsign=(c&16)===16,s.reserved=(c&8)===8,s.sslCA=(c&4)===4,s.emailCA=(c&2)===2,s.objCA=(c&1)===1}else if(s.name==="subjectAltName"||s.name==="issuerAltName"){s.altNames=[];var m,l=t.fromDer(s.value);for(var g=0;g2)throw{message:"Cannot read notBefore/notAfter validity times; more than two times were provided in the certificate."};if(b.length<2)throw{message:"Cannot read notBefore/notAfter validity times; they were not provided as either UTCTime or GeneralizedTime."};v.validity.notBefore=b[0],v.validity.notAfter=b[1],v.tbsCertificate=u.tbsCertificate;if(s){v.md=null;if(v.signatureOid in r){var d=r[v.signatureOid];switch(d){case"sha1WithRSAEncryption":v.md=e.md.sha1.create();break;case"md5WithRSAEncryption":v.md=e.md.md5.create();break;case"sha256WithRSAEncryption":v.md=e.md.sha256.create();break;case"RSASSA-PSS":v.md=e.md.sha256.create()}}if(v.md===null)throw{message:"Could not compute certificate digest. Unknown signature OID.",signatureOid:v.signatureOid};var w=t.toDer(v.tbsCertificate);v.md.update(w.getBytes())}var E=e.md.sha1.create();v.issuer.getField=function(e){return l(v.issuer,e)},v.issuer.addField=function(e){m([e]),v.issuer.attributes.push(e)},v.issuer.attributes=n.RDNAttributesAsArray(u.certIssuer,E),u.certIssuerUniqueId&&(v.issuer.uniqueId=u.certIssuerUniqueId),v.issuer.hash=E.digest().toHex();var S=e.md.sha1.create();return v.subject.getField=function(e){return l(v.subject,e)},v.subject.addField=function(e){m([e]),v.subject.attributes.push(e)},v.subject.attributes=n.RDNAttributesAsArray(u.certSubject,S),u.certSubjectUniqueId&&(v.subject.uniqueId=u.certSubjectUniqueId),v.subject.hash=S.digest().toHex(),u.certExtensions?v.extensions=c(u.certExtensions):v.extensions=[],v.publicKey=n.publicKeyFromAsn1(u.subjectPublicKeyInfo),v},n.certificationRequestFromAsn1=function(i,s){var o={},u=[];if(!t.validate(i,f,o,u))throw{message:"Cannot read PKCS#10 certificate request. ASN.1 object is not a PKCS#10 CertificationRequest.",errors:u};if(typeof o.csrSignature!="string"){var a="\0";for(var c=0;c0&&i.value.push(d(r.extensions)),i},n.getCertificationRequestInfo=function(e){var r=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,t.integerToDer(e.version).getBytes()),p(e.subject),n.publicKeyToAsn1(e.publicKey),y(e)]);return r},n.distinguishedNameToAsn1=function(e){return p(e)},n.certificateToAsn1=function(e){var r=e.tbsCertificate||n.getTBSCertificate(e);return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[r,t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(e.signatureOid).getBytes()),g(e.signatureOid,e.signatureParameters)]),t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,String.fromCharCode(0)+e.signature)])},n.certificationRequestToAsn1=function(e){var r=e.certificationRequestInfo||n.getCertificationRequestInfo(e);return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[r,t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(e.signatureOid).getBytes()),g(e.signatureOid,e.signatureParameters)]),t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,String.fromCharCode(0)+e.signature)])},n.createCaStore=function(t){var r={certs:{}};r.getIssuer=function(t){var i=null;if(!t.issuer.hash){var s=e.md.sha1.create();t.issuer.attributes=n.RDNAttributesAsArray(p(t.issuer),s),t.issuer.hash=s.digest().toHex()}if(t.issuer.hash in r.certs){i=r.certs[t.issuer.hash];if(e.util.isArray(i))throw{message:"Resolving multiple issuer matches not implemented yet."}}return i},r.addCertificate=function(t){typeof t=="string"&&(t=e.pki.certificateFromPem(t));if(!t.subject.hash){var i=e.md.sha1.create();t.subject.attributes=n.RDNAttributesAsArray(p(t.subject),i),t.subject.hash=i.digest().toHex()}if(t.subject.hash in r.certs){var s=r.certs[t.subject.hash];e.util.isArray(s)||(s=[s]),s.push(t)}else r.certs[t.subject.hash]=t};if(t)for(var i=0;ic.validity.notAfter)a={message:"Certificate is not valid yet or has expired.",error:n.certificateError.certificate_expired,notBefore:c.validity.notBefore,notAfter:c.validity.notAfter,now:o};else{var h=!1;if(r.length>0){l=r[0];try{h=l.verify(c)}catch(p){}}else{var d=t.getIssuer(c);if(d===null)a={message:"Certificate is not trusted.",error:n.certificateError.unknown_ca};else{e.util.isArray(d)||(d=[d]);while(!h&&d.length>0){l=d.shift();try{h=l.verify(c)}catch(p){}}}}a===null&&!h&&(a={message:"Certificate signature is invalid.",error:n.certificateError.bad_certificate})}a===null&&!c.isIssuer(l)&&(a={message:"Certificate issuer is invalid.",error:n.certificateError.bad_certificate});if(a===null){var v={keyUsage:!0,basicConstraints:!0};for(var m=0;a===null&&mE&&(a={message:"Certificate basicConstraints pathLenConstraint violated.",error:n.certificateError.bad_certificate})}}var S=a===null?!0:a.error,x=i?i(S,f,s):S;if(x!==!0){S===!0&&(a={message:"The application rejected the certificate.",error:n.certificateError.bad_certificate});if(x||x===0)typeof x=="object"&&!e.util.isArray(x)?(x.message&&(a.message=x.message),x.error&&(a.error=x.error)):typeof x=="string"&&(a.error=x);throw a}a=null,u=!1,++f}while(r.length>0);return!0}}var r="x509";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=0&&i.push(u)}return i}function l(e,r,s,o){r=t.fromDer(r,s);if(r.tagClass!==t.Class.UNIVERSAL||r.type!==t.Type.SEQUENCE||r.constructed!==!0)throw{message:"PKCS#12 AuthenticatedSafe expected to be a SEQUENCE OF ContentInfo"};for(var u=0;u0&&(f=t.create(t.Class.UNIVERSAL,t.Type.SET,!0,h));var p=[],d=[];s!==null&&(e.util.isArray(s)?d=s:d=[s]);var v=[];for(var m=0;m0){var w=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,v),E=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.data).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(w).getBytes())])]);p.push(E)}var S=null;if(i!==null){var x=n.wrapRsaPrivateKey(n.privateKeyToAsn1(i));o===null?S=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.keyBag).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[x]),f]):S=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.pkcs8ShroudedKeyBag).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[n.encryptPrivateKeyInfo(x,o,u)]),f]);var T=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[S]),N=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.data).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(T).getBytes())])]);p.push(N)}var C=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,p),k;if(u.useMac){var c=e.md.sha1.create(),L=new e.util.ByteBuffer(e.random.getBytes(u.saltSize)),A=u.count,i=r.generateKey(o||"",L,3,A,20),O=e.hmac.create();O.start(c,i),O.update(t.toDer(C).getBytes());var M=O.getMac();k=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.sha1).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,"")]),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,M.getBytes())]),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,L.getBytes()),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,t.integerToDer(A).getBytes())])}return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,t.integerToDer(3).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.data).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(C).getBytes())])]),k])},r.generateKey=e.pbe.generatePkcs12Key}var r="pkcs12";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o>1,u=o+(t.length&1),a=t.substr(0,u),f=t.substr(o,u),l=e.util.createBuffer(),c=e.hmac.create();r=n+r;var h=Math.ceil(i/16),p=Math.ceil(i/20);c.start("MD5",a);var d=e.util.createBuffer();l.putBytes(r);for(var v=0;v0&&(a.queue(e,a.createAlert({level:a.Alert.Level.warning,description:a.Alert.Description.no_renegotiation})),a.flush(e)),e.process()},a.parseHelloMessage=function(t,n,r){var i=null,s=t.entity===a.ConnectionEnd.client;if(r<38)t.error(t,{message:s?"Invalid ServerHello message. Message too short.":"Invalid ClientHello message. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var u=n.fragment,f=u.length();i={version:{major:u.getByte(),minor:u.getByte()},random:e.util.createBuffer(u.getBytes(32)),session_id:o(u,1),extensions:[]},s?(i.cipher_suite=u.getBytes(2),i.compression_method=u.getByte()):(i.cipher_suites=o(u,2),i.compression_methods=o(u,1)),f=r-(f-u.length());if(f>0){var l=o(u,2);while(l.length()>0)i.extensions.push({type:[l.getByte(),l.getByte()],data:o(l,2)});if(!s)for(var c=0;c0){var d=p.getByte();if(d!==0)break;t.session.serverNameList.push(o(p,2).getBytes())}}}}(i.version.major!==a.Version.major||i.version.minor!==a.Version.minor)&&t.error(t,{message:"Incompatible TLS version.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.protocol_version}});if(s)t.session.cipherSuite=a.getCipherSuite(i.cipher_suite);else{var v=e.util.createBuffer(i.cipher_suites.bytes());while(v.length()>0){t.session.cipherSuite=a.getCipherSuite(v.getBytes(2));if(t.session.cipherSuite!==null)break}}if(t.session.cipherSuite===null)return t.error(t,{message:"No cipher suites in common.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.handshake_failure},cipherSuite:e.util.bytesToHex(i.cipher_suite)});s?t.session.compressionMethod=i.compression_method:t.session.compressionMethod=a.CompressionMethod.none}return i},a.createSecurityParameters=function(e,t){var n=e.entity===a.ConnectionEnd.client,r=t.random.bytes(),i=n?e.session.sp.client_random:r,s=n?r:a.createRandom().getBytes();e.session.sp={entity:e.entity,prf_algorithm:a.PRFAlgorithm.tls_prf_sha256,bulk_cipher_algorithm:null,cipher_type:null,enc_key_length:null,block_length:null,fixed_iv_length:null,record_iv_length:null,mac_algorithm:null,mac_length:null,mac_key_length:null,compression_algorithm:e.session.compressionMethod,pre_master_secret:null,master_secret:null,client_random:i,server_random:s}},a.handleServerHello=function(e,t,n){var r=a.parseHelloMessage(e,t,n);if(!e.fail){var i=r.session_id.bytes();i.length>0&&i===e.session.id?(e.expect=d,e.session.resuming=!0,e.session.sp.server_random=r.random.bytes()):(e.expect=l,e.session.resuming=!1,a.createSecurityParameters(e,r)),e.session.id=i,e.process()}},a.handleClientHello=function(t,n,r){var i=a.parseHelloMessage(t,n,r);if(!t.fail){var s=i.session_id.bytes(),o=null;t.sessionCache&&(o=t.sessionCache.getSession(s),o===null&&(s="")),s.length===0&&(s=e.random.getBytes(32)),t.session.id=s,t.session.clientHelloVersion=i.version,t.session.sp=o?o.sp:{},o!==null?(t.expect=S,t.session.resuming=!0,t.session.sp.client_random=i.random.bytes()):(t.expect=t.verifyClient!==!1?b:w,t.session.resuming=!1,a.createSecurityParameters(t,i)),t.open=!0,a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createServerHello(t)})),t.session.resuming?(a.queue(t,a.createRecord({type:a.ContentType.change_cipher_spec,data:a.createChangeCipherSpec()})),t.state.pending=a.createConnectionState(t),t.state.current.write=t.state.pending.write,a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createFinished(t)}))):(a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createCertificate(t)})),t.fail||(a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createServerKeyExchange(t)})),t.verifyClient!==!1&&a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createCertificateRequest(t)})),a.queue(t,a.createRecord({type:a.ContentType.handshake,data:a.createServerHelloDone(t)})))),a.flush(t),t.process()}},a.handleCertificate=function(t,n,r){if(r<3)t.error(t,{message:"Invalid Certificate message. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var i=n.fragment,s={certificate_list:o(i,3)},u,f,l=[];try{while(s.certificate_list.length()>0)u=o(s.certificate_list,3),f=e.asn1.fromDer(u),u=e.pki.certificateFromAsn1(f,!0),l.push(u)}catch(h){t.error(t,{message:"Could not parse certificate list.",cause:h,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.bad_certificate}})}if(!t.fail){var p=t.entity===a.ConnectionEnd.client;!p&&t.verifyClient!==!0||l.length!==0?l.length===0?t.expect=p?c:w:(p?t.session.serverCertificate=l[0]:t.session.clientCertificate=l[0],a.verifyCertificateChain(t,l)&&(t.expect=p?c:w)):t.error(t,{message:p?"No server certificate provided.":"No client certificate provided.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}}),t.process()}}},a.handleServerKeyExchange=function(e,t,n){n>0?e.error(e,{message:"Invalid key parameters. Only RSA is supported.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.unsupported_certificate}}):(e.expect=h,e.process())},a.handleClientKeyExchange=function(t,n,r){if(r<48)t.error(t,{message:"Invalid key parameters. Only RSA is supported.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.unsupported_certificate}});else{var i=n.fragment,s={enc_pre_master_secret:o(i,2).getBytes()},u=null;if(t.getPrivateKey)try{u=t.getPrivateKey(t,t.session.serverCertificate),u=e.pki.privateKeyFromPem(u)}catch(f){t.error(t,{message:"Could not get private key.",cause:f,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}})}if(u===null)t.error(t,{message:"No private key set.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}});else try{var l=t.session.sp;l.pre_master_secret=u.decrypt(s.enc_pre_master_secret);var c=t.session.clientHelloVersion;if(c.major!==l.pre_master_secret.charCodeAt(0)||c.minor!==l.pre_master_secret.charCodeAt(1))throw{message:"TLS version rollback attack detected."}}catch(f){l.pre_master_secret=e.random.getBytes(48)}}t.fail||(t.expect=S,t.session.clientCertificate!==null&&(t.expect=E),t.process())},a.handleCertificateRequest=function(e,t,n){if(n<3)e.error(e,{message:"Invalid CertificateRequest. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var r=t.fragment,i={certificate_types:o(r,1),certificate_authorities:o(r,2)};e.session.certificateRequest=i,e.expect=p,e.process()}},a.handleCertificateVerify=function(t,n,r){if(r<2)t.error(t,{message:"Invalid CertificateVerify. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var i=n.fragment;i.read-=4;var s=i.bytes();i.read+=4;var u={signature:o(i,2).getBytes()},f=e.util.createBuffer();f.putBuffer(t.session.md5.digest()),f.putBuffer(t.session.sha1.digest()),f=f.getBytes();try{var l=t.session.clientCertificate;if(!l.publicKey.verify(f,u.signature,"NONE"))throw{message:"CertificateVerify signature does not match."};t.session.md5.update(s),t.session.sha1.update(s)}catch(c){t.error(t,{message:"Bad signature in CertificateVerify.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.handshake_failure}})}t.fail||(t.expect=S,t.process())}},a.handleServerHelloDone=function(t,n,r){if(r>0)t.error(t,{message:"Invalid ServerHelloDone message. Invalid length.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.record_overflow}});else if(t.serverCertificate===null){var i={message:"No server certificate provided. Not enough security.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.insufficient_security}},s=t.verify(t,i.alert.description,depth,[]);if(s===!0)i=null;else{if(s||s===0)typeof s=="object"&&!e.util.isArray(s)?(s.message&&(i.message=s.message),s.alert&&(i.alert.description=s.alert)):typeof s=="number"&&(i.alert.description=s);t.error(t,i)}}!t.fail&&t.session.certificateRequest!==null&&(n=a.createRecord({type:a.ContentType.handshake,data:a.createCertificate(t)}),a.queue(t,n));if(!t.fail){n=a.createRecord({type:a.ContentType.handshake,data:a.createClientKeyExchange(t)}),a.queue(t,n),t.expect=g;var o=function(e,t){e.session.certificateRequest!==null&&e.session.clientCertificate!==null&&a.queue(e,a.createRecord({type:a.ContentType.handshake,data:a.createCertificateVerify(e,t)})),a.queue(e,a.createRecord({type:a.ContentType.change_cipher_spec,data:a.createChangeCipherSpec()})),e.state.pending=a.createConnectionState(e),e.state.current.write=e.state.pending.write,a.queue(e,a.createRecord({type:a.ContentType.handshake,data:a.createFinished(e)})),e.expect=d,a.flush(e),e.process()};t.session.certificateRequest===null||t.session.clientCertificate===null?o(t,null):a.getClientSignature(t,o)}},a.handleChangeCipherSpec=function(e,t){if(t.fragment.getByte()!==1)e.error(e,{message:"Invalid ChangeCipherSpec message received.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var n=e.entity===a.ConnectionEnd.client;if(e.session.resuming&&n||!e.session.resuming&&!n)e.state.pending=a.createConnectionState(e);e.state.current.read=e.state.pending.read;if(!e.session.resuming&&n||e.session.resuming&&!n)e.state.pending=null;e.expect=n?v:x,e.process()}},a.handleFinished=function(n,r,i){var s=r.fragment;s.read-=4;var o=s.bytes();s.read+=4;var u=r.fragment.getBytes();s=e.util.createBuffer(),s.putBuffer(n.session.md5.digest()),s.putBuffer(n.session.sha1.digest());var f=n.entity===a.ConnectionEnd.client,l=f?"server finished":"client finished",c=n.session.sp,h=12,p=t;s=p(c.master_secret,l,s.getBytes(),h);if(s.getBytes()!==u)n.error(n,{message:"Invalid verify_data in Finished message.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.decrypt_error}});else{n.session.md5.update(o),n.session.sha1.update(o);if(n.session.resuming&&f||!n.session.resuming&&!f)a.queue(n,a.createRecord({type:a.ContentType.change_cipher_spec,data:a.createChangeCipherSpec()})),n.state.current.write=n.state.pending.write,n.state.pending=null,a.queue(n,a.createRecord({type:a.ContentType.handshake,data:a.createFinished(n)}));n.expect=f?m:T,n.handshaking=!1,++n.handshakes,n.peerCertificate=f?n.session.serverCertificate:n.session.clientCertificate,n.sessionCache?(n.session={id:n.session.id,sp:n.session.sp},n.session.sp.keys=null):n.session=null,a.flush(n),n.isConnected=!0,n.connected(n),n.process()}},a.handleAlert=function(e,t){var n=t.fragment,r={level:n.getByte(),description:n.getByte()},i;switch(r.description){case a.Alert.Description.close_notify:i="Connection closed.";break;case a.Alert.Description.unexpected_message:i="Unexpected message.";break;case a.Alert.Description.bad_record_mac:i="Bad record MAC.";break;case a.Alert.Description.decryption_failed:i="Decryption failed.";break;case a.Alert.Description.record_overflow:i="Record overflow.";break;case a.Alert.Description.decompression_failure:i="Decompression failed.";break;case a.Alert.Description.handshake_failure:i="Handshake failure.";break;case a.Alert.Description.bad_certificate:i="Bad certificate.";break;case a.Alert.Description.unsupported_certificate:i="Unsupported certificate.";break;case a.Alert.Description.certificate_revoked:i="Certificate revoked.";break;case a.Alert.Description.certificate_expired:i="Certificate expired.";break;case a.Alert.Description.certificate_unknown:i="Certificate unknown.";break;case a.Alert.Description.illegal_parameter:i="Illegal parameter.";break;case a.Alert.Description.unknown_ca:i="Unknown certificate authority.";break;case a.Alert.Description.access_denied:i="Access denied.";break;case a.Alert.Description.decode_error:i="Decode error.";break;case a.Alert.Description.decrypt_error:i="Decrypt error.";break;case a.Alert.Description.export_restriction:i="Export restriction.";break;case a.Alert.Description.protocol_version:i="Unsupported protocol version.";break;case a.Alert.Description.insufficient_security:i="Insufficient security.";break;case a.Alert.Description.internal_error:i="Internal error.";break;case a.Alert.Description.user_canceled:i="User canceled.";break;case a.Alert.Description.no_renegotiation:i="Renegotiation not supported.";break;default:i="Unknown error."}r.description===a.Alert.Description.close_notify?e.close():(e.error(e,{message:i,send:!1,origin:e.entity===a.ConnectionEnd.client?"server":"client",alert:r}),e.process())},a.handleHandshake=function(t,n){var r=n.fragment,i=r.getByte(),s=r.getInt24();if(s>r.length())t.fragmented=n,n.fragment=e.util.createBuffer(),r.read-=4,t.process();else{t.fragmented=null,r.read-=4;var o=r.bytes(s+4);r.read+=4,i in I[t.entity][t.expect]?(t.entity===a.ConnectionEnd.server&&!t.open&&!t.fail&&(t.handshaking=!0,t.session={serverNameList:[],cipherSuite:null,compressionMethod:null,serverCertificate:null,clientCertificate:null,md5:e.md.md5.create(),sha1:e.md.sha1.create()}),i!==a.HandshakeType.hello_request&&i!==a.HandshakeType.certificate_verify&&i!==a.HandshakeType.finished&&(t.session.md5.update(o),t.session.sha1.update(o)),I[t.entity][t.expect][i](t,n,s)):a.handleUnexpected(t,n)}},a.handleApplicationData=function(e,t){e.data.putBuffer(t.fragment),e.dataReady(e),e.process()};var f=0,l=1,c=2,h=3,p=4,d=5,v=6,m=7,g=8,y=0,b=1,w=2,E=3,S=4,x=5,T=6,N=7,C=a.handleUnexpected,k=a.handleChangeCipherSpec,L=a.handleAlert,A=a.handleHandshake,O=a.handleApplicationData,M=[];M[a.ConnectionEnd.client]=[[C,L,A,C],[C,L,A,C],[C,L,A,C],[C,L,A,C],[C,L,A,C],[k,L,C,C],[C,L,A,C],[C,L,A,O],[C,L,A,C]],M[a.ConnectionEnd.server]=[[C,L,A,C],[C,L,A,C],[C,L,A,C],[C,L,A,C],[k,L,C,C],[C,L,A,C],[C,L,A,O],[C,L,A,C]];var _=a.handleHelloRequest,D=a.handleServerHello,P=a.handleCertificate,H=a.handleServerKeyExchange,B=a.handleCertificateRequest,j=a.handleServerHelloDone,F=a.handleFinished,I=[];I[a.ConnectionEnd.client]=[[C,C,D,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,P,H,B,j,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,H,B,j,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,B,j,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,j,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,F],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[_,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C]];var q=a.handleClientHello,R=a.handleClientKeyExchange,U=a.handleCertificateVerify;I[a.ConnectionEnd.server]=[[C,q,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,P,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,R,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,U,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,F],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C]],a.generateKeys=function(e,n){var r=t,i=n.client_random+n.server_random;e.session.resuming||(n.master_secret=r(n.pre_master_secret,"master secret",i,48).bytes(),n.pre_master_secret=null),i=n.server_random+n.client_random;var s=2*n.mac_key_length+2*n.enc_key_length+2*n.fixed_iv_length,o=r(n.master_secret,"key expansion",i,s);return{client_write_MAC_key:o.getBytes(n.mac_key_length),server_write_MAC_key:o.getBytes(n.mac_key_length),client_write_key:o.getBytes(n.enc_key_length),server_write_key:o.getBytes(n.enc_key_length),client_write_IV:o.getBytes(n.fixed_iv_length),server_write_IV:o.getBytes(n.fixed_iv_length)}},a.createConnectionState=function(e){var t=e.entity===a.ConnectionEnd.client,n=function(){var e={sequenceNumber:[0,0],macKey:null,macLength:0,macFunction:null,cipherState:null,cipherFunction:function(e){return!0},compressionState:null,compressFunction:function(e){return!0},updateSequenceNumber:function(){e.sequenceNumber[1]===4294967295?(e.sequenceNumber[1]=0,++e.sequenceNumber[0]):++e.sequenceNumber[1]}};return e},r={read:n(),write:n()};r.read.update=function(e,t){return r.read.cipherFunction(t,r.read)?r.read.compressFunction(e,t,r.read)||e.error(e,{message:"Could not decompress record.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.decompression_failure}}):e.error(e,{message:"Could not decrypt record or bad MAC.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.bad_record_mac}}),!e.fail},r.write.update=function(e,t){return r.write.compressFunction(e,t,r.write)?r.write.cipherFunction(t,r.write)||e.error(e,{message:"Could not encrypt record.",send:!1,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}}):e.error(e,{message:"Could not compress record.",send:!1,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}}),!e.fail};if(e.session){var o=e.session.sp;e.session.cipherSuite.initSecurityParameters(o),o.keys=a.generateKeys(e,o),r.read.macKey=t?o.keys.server_write_MAC_key:o.keys.client_write_MAC_key,r.write.macKey=t?o.keys.client_write_MAC_key:o.keys.server_write_MAC_key,e.session.cipherSuite.initConnectionState(r,e,o);switch(o.compression_algorithm){case a.CompressionMethod.none:break;case a.CompressionMethod.deflate:r.read.compressFunction=s,r.write.compressFunction=i;break;default:throw{message:"Unsupported compression algorithm."}}}return r},a.createRandom=function(){var t=new Date,n=+t+t.getTimezoneOffset()*6e4,r=e.util.createBuffer();return r.putInt32(n),r.putBytes(e.random.getBytes(28)),r},a.createRecord=function(e){if(!e.data)return null;var t={type:e.type,version:{major:a.Version.major,minor:a.Version.minor},length:e.data.length(),fragment:e.data};return t},a.createAlert=function(t){var n=e.util.createBuffer();return n.putByte(t.level),n.putByte(t.description),a.createRecord({type:a.ContentType.alert,data:n})},a.createClientHello=function(t){var n=e.util.createBuffer();for(var r=0;r0&&(d+=2);var v=t.session.id,m=v.length+1+2+4+28+2+s+1+f+d,g=e.util.createBuffer();return g.putByte(a.HandshakeType.client_hello),g.putInt24(m),g.putByte(a.Version.major),g.putByte(a.Version.minor),g.putBytes(t.session.sp.client_random),u(g,1,e.util.createBuffer(v)),u(g,2,n),u(g,1,o),d>0&&u(g,2,l),g},a.createServerHello=function(t){var n=t.session.id,r=n.length+1+2+4+28+2+1,i=e.util.createBuffer();return i.putByte(a.HandshakeType.server_hello),i.putInt24(r),i.putByte(a.Version.major),i.putByte(a.Version.minor),i.putBytes(t.session.sp.server_random),u(i,1,e.util.createBuffer(n)),i.putByte(t.session.cipherSuite.id[0]),i.putByte(t.session.cipherSuite.id[1]),i.putByte(t.session.compressionMethod),i},a.createCertificate=function(t){var n=t.entity===a.ConnectionEnd.client,r=null;t.getCertificate&&(r=t.getCertificate(t,n?t.session.certificateRequest:t.session.serverNameList));var i=e.util.createBuffer();if(r!==null)try{e.util.isArray(r)||(r=[r]);var s=null;for(var o=0;o0&&(r.putByte(a.HandshakeType.server_key_exchange),r.putInt24(n)),r},a.getClientSignature=function(t,n){var r=e.util.createBuffer();r.putBuffer(t.session.md5.digest()),r.putBuffer(t.session.sha1.digest()),r=r.getBytes(),t.getSignature=t.getSignature||function(t,n,r){var i=null;if(t.getPrivateKey)try{i=t.getPrivateKey(t,t.session.clientCertificate),i=e.pki.privateKeyFromPem(i)}catch(s){t.error(t,{message:"Could not get private key.",cause:s,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}})}i===null?t.error(t,{message:"No private key set.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}}):n=i.sign(n,null),r(t,n)},t.getSignature(t,r,n)},a.createCertificateVerify=function(t,n){var r=n.length+2,i=e.util.createBuffer();return i.putByte(a.HandshakeType.certificate_verify),i.putInt24(r),i.putInt16(n.length),i.putBytes(n),i},a.createCertificateRequest=function(t){var n=e.util.createBuffer();n.putByte(1);var r=e.util.createBuffer();for(var i in t.caStore.certs){var s=t.caStore.certs[i],o=e.pki.distinguishedNameToAsn1(s.subject);r.putBuffer(e.asn1.toDer(o))}var f=1+n.length()+2+r.length(),l=e.util.createBuffer();return l.putByte(a.HandshakeType.certificate_request),l.putInt24(f),u(l,1,n),u(l,2,r),l},a.createServerHelloDone=function(t){var n=e.util.createBuffer();return n.putByte(a.HandshakeType.server_hello_done),n.putInt24(0),n},a.createChangeCipherSpec=function(){var t=e.util.createBuffer();return t.putByte(1),t},a.createFinished=function(n){var r=e.util.createBuffer();r.putBuffer(n.session.md5.digest()),r.putBuffer(n.session.sha1.digest());var i=n.entity===a.ConnectionEnd.client,s=n.session.sp,o=12,u=t,f=i?"client finished":"server finished";r=u(s.master_secret,f,r.getBytes(),o);var l=e.util.createBuffer();return l.putByte(a.HandshakeType.finished),l.putInt24(r.length()),l.putBuffer(r),l},a.queue=function(t,n){if(!n)return;if(n.type===a.ContentType.handshake){var r=n.fragment.bytes();t.session.md5.update(r),t.session.sha1.update(r),r=null}var i;if(n.fragment.length()<=a.MaxFragment)i=[n];else{i=[];var s=n.fragment.bytes();while(s.length>a.MaxFragment)i.push(a.createRecord({type:n.type,data:e.util.createBuffer(s.slice(0,a.MaxFragment))})),s=s.slice(a.MaxFragment);s.length>0&&i.push(a.createRecord({type:n.type,data:e.util.createBuffer(s)}))}for(var o=0;o0&&(i=r.order[0]);if(i!==null&&i in r.cache){n=r.cache[i],delete r.cache[i];for(var s in r.order)if(r.order[s]===i){r.order.splice(s,1);break}}return n},r.setSession=function(t,n){if(r.order.length===r.capacity){var i=r.order.shift();delete r.cache[i]}var i=e.util.bytesToHex(t);r.order.push(i),r.cache[i]=n}}return r},a.createConnection=function(t){var n=null;t.caStore?e.util.isArray(t.caStore)?n=e.pki.createCaStore(t.caStore):n=t.caStore:n=e.pki.createCaStore();var r=t.cipherSuites||null;if(r===null){r=[];for(var i in a.CipherSuites)r.push(a.CipherSuites[i])}var s=t.server||!1?a.ConnectionEnd.server:a.ConnectionEnd.client,o=t.sessionCache?a.createSessionCache(t.sessionCache):null,u={entity:s,sessionId:t.sessionId,caStore:n,sessionCache:o,cipherSuites:r,connected:t.connected,virtualHost:t.virtualHost||null,verifyClient:t.verifyClient||!1,verify:t.verify||function(e,t,n,r){return t},getCertificate:t.getCertificate||null,getPrivateKey:t.getPrivateKey||null,getSignature:t.getSignature||null,input:e.util.createBuffer(),tlsData:e.util.createBuffer(),data:e.util.createBuffer(),tlsDataReady:t.tlsDataReady,dataReady:t.dataReady,closed:t.closed,error:function(e,n){n.origin=n.origin||(e.entity===a.ConnectionEnd.client?"client":"server"),n.send&&(a.queue(e,a.createAlert(n.alert)),a.flush(e));var r=n.fatal!==!1;r&&(e.fail=!0),t.error(e,n),r&&e.close(!1)},deflate:t.deflate||null,inflate:t.inflate||null};u.reset=function(e){u.record=null,u.session=null,u.peerCertificate=null,u.state={pending:null,current:null},u.expect=u.entity===a.ConnectionEnd.client?f:y,u.fragmented=null,u.records=[],u.open=!1,u.handshakes=0,u.handshaking=!1,u.isConnected=!1,u.fail=!e&&typeof e!="undefined",u.input.clear(),u.tlsData.clear(),u.data.clear(),u.state.current=a.createConnectionState(u)},u.reset();var l=function(e,t){var n=t.type-a.ContentType.change_cipher_spec,r=M[e.entity][e.expect];n in r?r[n](e,t):a.handleUnexpected(e,t)},c=function(t){var n=0,r=t.input,i=r.length();return i<5?n=5-i:(t.record={type:r.getByte(),version:{major:r.getByte(),minor:r.getByte()},length:r.getInt16(),fragment:e.util.createBuffer(),ready:!1},(t.record.version.major!==a.Version.major||t.record.version.minor!==a.Version.minor)&&t.error(t,{message:"Incompatible TLS version.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.protocol_version}})),n},h=function(e){var t=0,n=e.input,r=n.length();if(r0&&(u.sessionCache&&(n=u.sessionCache.getSession(t)),n===null&&(t="")),t.length===0&&u.sessionCache&&(n=u.sessionCache.getSession(),n!==null&&(t=n.id)),u.session={id:t,cipherSuite:null,compressionMethod:null,serverCertificate:null,certificateRequest:null,clientCertificate:null,sp:n?n.sp:{},md5:e.md.md5.create(),sha1:e.md.sha1.create()},u.session.sp.client_random=a.createRandom().getBytes(),u.open=!0,a.queue(u,a.createRecord({type:a.ContentType.handshake,data:a.createClientHello(u)})),a.flush(u)}},u.process=function(e){var t=0;return e&&u.input.putBytes(e),u.fail||(u.record!==null&&u.record.ready&&u.record.fragment.isEmpty()&&(u.record=null),u.record===null&&(t=c(u)),!u.fail&&u.record!==null&&!u.record.ready&&(t=h(u)),!u.fail&&u.record!==null&&u.record.ready&&l(u,u.record)),t},u.prepare=function(t){return a.queue(u,a.createRecord({type:a.ContentType.application_data,data:e.util.createBuffer(t)})),a.flush(u)},u.close=function(e){!u.fail&&u.sessionCache&&u.session&&u.sessionCache.setSession(u.session.id,u.session);if(u.open){u.open=!1,u.input.clear();if(u.isConnected||u.handshaking)u.isConnected=u.handshaking=!1,a.queue(u,a.createAlert({level:a.Alert.Level.warning,description:a.Alert.Description.close_notify})),a.flush(u);u.closed(u)}u.reset(e)},u},e.tls=e.tls||{};for(var X in a)typeof a[X]!="function"&&(e.tls[X]=a[X]);e.tls.prf_tls1=t,e.tls.hmac_sha1=r,e.tls.createSessionCache=a.createSessionCache,e.tls.createConnection=a.createConnection}var r="tls";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o1?o=e.random.getBytes(16):o=n.cipherState.init?null:n.cipherState.iv,n.cipherState.init=!0;var u=n.cipherState.cipher;return u.start(o),t.version.minor>1&&u.output.putBytes(o),u.update(t.fragment),u.finish(i)&&(t.fragment=u.output,t.length=t.fragment.length(),r=!0),r}function i(e,t,n){if(!n){var r=e-t.length()%e;t.fillWithByte(r-1,r)}return!0}function s(e,t,n){var r=!0;if(n){var i=t.length(),s=t.last();for(var o=i-1-s;o=u?(t.fragment=o.output.getBytes(l-u),a=o.output.getBytes(u)):t.fragment=o.output.getBytes(),t.fragment=e.util.createBuffer(t.fragment),t.length=t.fragment.length();var c=n.macFunction(n.macKey,n.sequenceNumber,t);return n.updateSequenceNumber(),r=c===a&&r,r}var t=e.tls;t.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA={id:[0,47],name:"TLS_RSA_WITH_AES_128_CBC_SHA",initSecurityParameters:function(e){e.bulk_cipher_algorithm=t.BulkCipherAlgorithm.aes,e.cipher_type=t.CipherType.block,e.enc_key_length=16,e.block_length=16,e.fixed_iv_length=16,e.record_iv_length=16,e.mac_algorithm=t.MACAlgorithm.hmac_sha1,e.mac_length=20,e.mac_key_length=20},initConnectionState:n},t.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA={id:[0,53],name:"TLS_RSA_WITH_AES_256_CBC_SHA",initSecurityParameters:function(e){e.bulk_cipher_algorithm=t.BulkCipherAlgorithm.aes,e.cipher_type=t.CipherType.block,e.enc_key_length=32,e.block_length=16,e.fixed_iv_length=16,e.record_iv_length=16,e.mac_algorithm=t.MACAlgorithm.hmac_sha1,e.mac_length=20,e.mac_key_length=20},initConnectionState:n}}var r="aesCipherSuites";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=1&&e.log.verbose(t,"[%s][%s] init",this.id,this.name,this)};T.prototype.debug=function(n){n=n||"",e.log.debug(t,n,"[%s][%s] task:",this.id,this.name,this,"subtasks:",this.subtasks.length,"queue:",s)},T.prototype.next=function(e,t){typeof e=="function"&&(t=e,e=this.name);var n=new T({run:t,name:e,parent:this});return n.state=l,n.type=this.type,n.successCallback=this.successCallback||null,n.failureCallback=this.failureCallback||null,this.subtasks.push(n),this},T.prototype.parallel=function(t,n){return e.util.isArray(t)&&(n=t,t=this.name),this.next(t,function(r){var i=r;i.block(n.length);var s=function(t,r){e.task.start({type:t,run:function(e){n[r](e)},success:function(e){i.unblock()},failure:function(e){i.unblock()}})};for(var o=0;o0&&(this.state=x[this.state][g])},T.prototype.unblock=function(e){return e=typeof e=="undefined"?1:e,this.blocks-=e,this.blocks===0&&this.state!==p&&(this.state=l,C(this,0)),this.blocks},T.prototype.sleep=function(e){e=typeof e=="undefined"?0:e,this.state=x[this.state][b];var t=this;this.timeoutId=setTimeout(function(){t.timeoutId=null,t.state=l,C(t,0)},e)},T.prototype.wait=function(e){e.wait(this)},T.prototype.wakeup=function(){this.state===h&&(cancelTimeout(this.timeoutId),this.timeoutId=null,this.state=l,C(this,0))},T.prototype.cancel=function(){this.state=x[this.state][E],this.permitsNeeded=0,this.timeoutId!==null&&(cancelTimeout(this.timeoutId),this.timeoutId=null),this.subtasks=[]},T.prototype.fail=function(e){this.error=!0,k(this,!0);if(e)e.error=this.error,e.swapTime=this.swapTime,e.userData=this.userData,C(e,0);else{if(this.parent!==null){var t=this.parent;while(t.parent!==null)t.error=this.error,t.swapTime=this.swapTime,t.userData=this.userData,t=t.parent;k(t,!0)}this.failureCallback&&this.failureCallback(this)}};var N=function(e){e.error=!1,e.state=x[e.state][m],setTimeout(function(){e.state===l&&(e.swapTime=+(new Date),e.run(e),C(e,0))},0)},C=function(e,t){var n=t>u||+(new Date)-e.swapTime>a,r=function(t){t++;if(e.state===l){n&&(e.swapTime=+(new Date));if(e.subtasks.length>0){var r=e.subtasks.shift();r.error=e.error,r.swapTime=e.swapTime,r.userData=e.userData,r.run(r),r.error||C(r,t)}else k(e),e.error||e.parent!==null&&(e.parent.error=e.error,e.parent.swapTime=e.swapTime,e.parent.userData=e.userData,C(e.parent,t))}};n?setTimeout(r,0):r(t)},k=function(i,o){i.state=p,delete r[i.id],n>=1&&e.log.verbose(t,"[%s][%s] finish",i.id,i.name,i),i.parent===null&&(i.type in s?s[i.type].length===0?e.log.error(t,"[%s][%s] task queue empty [%s]",i.id,i.name,i.type):s[i.type][0]!==i?e.log.error(t,"[%s][%s] task not first in queue [%s]",i.id,i.name,i.type):(s[i.type].shift(),s[i.type].length===0?(n>=1&&e.log.verbose(t,"[%s][%s] delete queue [%s]",i.id,i.name,i.type),delete s[i.type]):(n>=1&&e.log.verbose(t,"[%s][%s] queue start next [%s] remain:%s",i.id,i.name,i.type,s[i.type].length),s[i.type][0].start())):e.log.error(t,"[%s][%s] task queue missing [%s]",i.id,i.name,i.type),o||(i.error&&i.failureCallback?i.failureCallback(i):!i.error&&i.successCallback&&i.successCallback(i)))};e.task=e.task||{},e.task.start=function(r){var i=new T({run:r.run,name:r.name||o});i.type=r.type,i.successCallback=r.success||null,i.failureCallback=r.failure||null,i.type in s?s[r.type].push(i):(n>=1&&e.log.verbose(t,"[%s][%s] create queue [%s]",i.id,i.name,i.type),s[i.type]=[i],N(i))},e.task.cancel=function(e){e in s&&(s[e]=[s[e][0]])},e.task.createCondition=function(){var e={tasks:{}};return e.wait=function(t){t.id in e.tasks||(t.block(),e.tasks[t.id]=t)},e.notify=function(){var t=e.tasks;e.tasks={};for(var n in t)t[n].unblock()},e}}var r="task";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o="8"&&(r="00"+r);var i=e.util.hexToBytes(r);t.putInt32(i.length),t.putBytes(i)}function r(e,t){e.putInt32(t.length),e.putString(t)}function i(){var t=e.md.sha1.create(),n=arguments.length;for(var r=0;r0&&(e.splice(c-1,2),c-=2)}}e=e.join("/")}else e.indexOf("./")===0&&(e=e.substring(2));if((v||g)&&m){n=e.split("/");for(c=n.length;c>0;c-=1){r=n.slice(0,c).join("/");if(v)for(h=v.length;h>0;h-=1){i=m[v.slice(0,h).join("/")];if(i){i=i[r];if(i){s=i,u=c;break}}}if(s)break;!a&&g&&g[r]&&(a=g[r],f=c)}!s&&a&&(s=a,u=f),s&&(n.splice(0,u,s),e=n.join("/"))}return e}function g(e,t){return function(){return s.apply(r,p.call(arguments,0).concat([e,t]))}}function y(e){return function(t){return m(t,e)}}function b(e){return function(t){a[e]=t}}function w(e){if(v(f,e)){var t=f[e];delete f[e],c[e]=!0,i.apply(r,t)}if(!v(a,e)&&!v(c,e))throw new Error("No "+e);return a[e]}function E(e){var t,n=e?e.indexOf("!"):-1;return n>-1&&(t=e.substring(0,n),e=e.substring(n+1,e.length)),[t,e]}function S(e){return function(){return l&&l.config&&l.config[e]||{}}}var i,s,o,u,a={},f={},l={},c={},h=Object.prototype.hasOwnProperty,p=[].slice,d=/\.js$/;o=function(e,t){var n,r=E(e),i=r[0];return e=r[1],i&&(i=m(i,t),n=w(i)),i?n&&n.normalize?e=n.normalize(e,y(t)):e=m(e,t):(e=m(e,t),r=E(e),i=r[0],e=r[1],i&&(n=w(i))),{f:i?i+"!"+e:e,n:e,pr:i,p:n}},u={require:function(e){return g(e)},exports:function(e){var t=a[e];return typeof t!="undefined"?t:a[e]={}},module:function(e){return{id:e,uri:"",exports:a[e],config:S(e)}}},i=function(e,t,n,i){var s,l,h,p,d,m=[],y=typeof n,E;i=i||e;if(y==="undefined"||y==="function"){t=!t.length&&n.length?["require","exports","module"]:t;for(d=0;d0)t&1&&(n+=e),t>>>=1,t>0&&(e+=e);return this.data=n,this},t.ByteBuffer.prototype.putBytes=function(e){return this.data+=e,this},t.ByteBuffer.prototype.putString=function(e){return this.data+=t.encodeUtf8(e),this},t.ByteBuffer.prototype.putInt16=function(e){return this.data+=String.fromCharCode(e>>8&255)+String.fromCharCode(e&255),this},t.ByteBuffer.prototype.putInt24=function(e){return this.data+=String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255),this},t.ByteBuffer.prototype.putInt32=function(e){return this.data+=String.fromCharCode(e>>24&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255),this},t.ByteBuffer.prototype.putInt16Le=function(e){return this.data+=String.fromCharCode(e&255)+String.fromCharCode(e>>8&255),this},t.ByteBuffer.prototype.putInt24Le=function(e){return this.data+=String.fromCharCode(e&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e>>16&255),this},t.ByteBuffer.prototype.putInt32Le=function(e){return this.data+=String.fromCharCode(e&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>24&255),this},t.ByteBuffer.prototype.putInt=function(e,t){do t-=8,this.data+=String.fromCharCode(e>>t&255);while(t>0);return this},t.ByteBuffer.prototype.putSignedInt=function(e,t){return e<0&&(e+=2<0);return t},t.ByteBuffer.prototype.getSignedInt=function(e){var t=this.getInt(e),n=2<=n&&(t-=n<<1),t},t.ByteBuffer.prototype.getBytes=function(e){var t;return e?(e=Math.min(this.length(),e),t=this.data.slice(this.read,this.read+e),this.read+=e):e===0?t="":(t=this.read===0?this.data:this.data.slice(this.read),this.clear()),t},t.ByteBuffer.prototype.bytes=function(e){return typeof e=="undefined"?this.data.slice(this.read):this.data.slice(this.read,this.read+e)},t.ByteBuffer.prototype.at=function(e){return this.data.charCodeAt(this.read+e)},t.ByteBuffer.prototype.setAt=function(e,t){return this.data=this.data.substr(0,this.read+e)+String.fromCharCode(t)+this.data.substr(this.read+e+1),this},t.ByteBuffer.prototype.last=function(){return this.data.charCodeAt(this.data.length-1)},t.ByteBuffer.prototype.copy=function(){var e=t.createBuffer(this.data);return e.read=this.read,e},t.ByteBuffer.prototype.compact=function(){return this.read>0&&(this.data=this.data.slice(this.read),this.read=0),this},t.ByteBuffer.prototype.clear=function(){return this.data="",this.read=0,this},t.ByteBuffer.prototype.truncate=function(e){var t=Math.max(0,this.length()-e);return this.data=this.data.substr(this.read,t),this.read=0,this},t.ByteBuffer.prototype.toHex=function(){var e="";for(var t=this.read;t0)t&1&&(n+=e),t>>>=1,t>0&&(e+=e);return n},t.xorBytes=function(e,t,n){var r="",i="",s="",o=0,u=0;for(;n>0;--n,++o)i=e.charCodeAt(o)^t.charCodeAt(o),u>=10&&(r+=s,s="",u=0),s+=String.fromCharCode(i),++u;return r+=s,r},t.hexToBytes=function(e){var t="",n=0;e.length&!0&&(n=1,t+=String.fromCharCode(parseInt(e[0],16)));for(;n>24&255)+String.fromCharCode(e>>16&255)+String.fromCharCode(e>>8&255)+String.fromCharCode(e&255)};var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",i=[62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];t.encode64=function(e,t){var n="",i="",s,o,u,a=0;while(a>2),n+=r.charAt((s&3)<<4|o>>4),isNaN(o)?n+="==":(n+=r.charAt((o&15)<<2|u>>6),n+=isNaN(u)?"=":r.charAt(u&63)),t&&n.length>t&&(i+=n.substr(0,t)+"\r\n",n=n.substr(t));return i+=n,i},t.decode64=function(e){e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");var t="",n,r,s,o,u=0;while(u>4),s!==64&&(t+=String.fromCharCode((r&15)<<4|s>>2),o!==64&&(t+=String.fromCharCode((s&3)<<6|o)));return t},t.encodeUtf8=function(e){return unescape(encodeURIComponent(e))},t.decodeUtf8=function(e){return decodeURIComponent(escape(e))},t.deflate=function(e,n,r){n=t.decode64(e.deflate(t.encode64(n)).rval);if(r){var i=2,s=n.charCodeAt(1);s&32&&(i=6),n=n.substring(i,n.length-4)}return n},t.inflate=function(e,n,r){var i=e.inflate(t.encode64(n)).rval;return i===null?null:t.decode64(i)};var s=function(e,n,r){if(!e)throw{message:"WebStorage not available."};var i;r===null?i=e.removeItem(n):(r=t.encode64(JSON.stringify(r)),i=e.setItem(n,r));if(typeof i!="undefined"&&i.rval!==!0)throw i.error},o=function(e,n){if(!e)throw{message:"WebStorage not available."};var r=e.getItem(n);if(e.init)if(r.rval===null){if(r.error)throw r.error;r=null}else r=r.rval;return r!==null&&(r=JSON.parse(t.decode64(r))),r},u=function(e,t,n,r){var i=o(e,t);i===null&&(i={}),i[n]=r,s(e,t,i)},a=function(e,t,n){var r=o(e,t);return r!==null&&(r=n in r?r[n]:null),r},f=function(e,t,n){var r=o(e,t);if(r!==null&&n in r){delete r[n];var i=!0;for(var u in r){i=!1;break}i&&(r=null),s(e,t,r)}},l=function(e,t){s(e,t,null)},c=function(e,t,n){var r=null;typeof n=="undefined"&&(n=["web","flash"]);var i,s=!1,o=null;for(var u in n){i=n[u];try{if(i==="flash"||i==="both"){if(t[0]===null)throw{message:"Flash local storage not available."};r=e.apply(this,t),s=i==="flash"}if(i==="web"||i==="both")t[0]=localStorage,r=e.apply(this,t),s=!0}catch(a){o=a}if(s)break}if(!s)throw o;return r};t.setItem=function(e,t,n,r,i){c(u,arguments,i)},t.getItem=function(e,t,n,r){return c(a,arguments,r)},t.removeItem=function(e,t,n,r){c(f,arguments,r)},t.clearItems=function(e,t,n){c(l,arguments,n)},t.parseUrl=function(e){var t=/^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g;t.lastIndex=0;var n=t.exec(e),r=n===null?null:{full:e,scheme:n[1],host:n[2],port:n[3],path:n[4]};return r&&(r.fullHost=r.host,r.port?r.port!==80&&r.scheme==="http"?r.fullHost+=":"+r.port:r.port!==443&&r.scheme==="https"&&(r.fullHost+=":"+r.port):r.scheme==="http"?r.port=80:r.scheme==="https"&&(r.port=443),r.full=r.scheme+"://"+r.fullHost),r};var h=null;t.getQueryVariables=function(e){var t=function(e){var t={},n=e.split("&");for(var r=0;r0?(s=n[r].substring(0,i),o=n[r].substring(i+1)):(s=n[r],o=null),s in t||(t[s]=[]),!(s in Object.prototype)&&o!==null&&t[s].push(unescape(o))}return t},n;return typeof e=="undefined"?(h===null&&(typeof window=="undefined"?h={}:h=t(window.location.search.substring(1))),n=h):n=t(e),n},t.parseFragment=function(e){var n=e,r="",i=e.indexOf("?");i>0&&(n=e.substring(0,i),r=e.substring(i+1));var s=n.split("/");s.length>0&&s[0]===""&&s.shift();var o=r===""?{}:t.getQueryVariables(r);return{pathString:n,queryString:r,path:s,query:o}},t.makeRequest=function(e){var n=t.parseFragment(e),r={path:n.pathString,query:n.queryString,getPath:function(e){return typeof e=="undefined"?n.path:n.path[e]},getQuery:function(e,t){var r;return typeof e=="undefined"?r=n.query:(r=n.query[e],r&&typeof t!="undefined"&&(r=r[t])),r},getQueryLast:function(e,t){var n,i=r.getQuery(e);return i?n=i[i.length-1]:n=t,n}};return r},t.makeLink=function(e,t,n){e=jQuery.isArray(e)?e.join("/"):e;var r=jQuery.param(t||{});return n=n||"",e+(r.length>0?"?"+r:"")+(n.length>0?"#"+n:"")},t.setPath=function(e,t,n){if(typeof e=="object"&&e!==null){var r=0,i=t.length;while(r0&&s.push(r),o=t.lastIndex;var u=n[0][1];switch(u){case"s":case"o":i");break;case"%":s.push("%");break;default:s.push("<%"+u+"?>")}}return s.push(e.substring(o)),s.join("")},t.formatNumber=function(e,t,n,r){var i=e,s=isNaN(t=Math.abs(t))?2:t,o=n===undefined?",":n,u=r===undefined?".":r,a=i<0?"-":"",f=parseInt(i=Math.abs(+i||0).toFixed(s),10)+"",l=f.length>3?f.length%3:0;return a+(l?f.substr(0,l)+u:"")+f.substr(l).replace(/(\d{3})(?=\d)/g,"$1"+u)+(s?o+Math.abs(i-f).toFixed(s).slice(2):"")},t.formatSize=function(e){return e>=1073741824?e=t.formatNumber(e/1073741824,2,".","")+" GiB":e>=1048576?e=t.formatNumber(e/1048576,2,".","")+" MiB":e>=1024?e=t.formatNumber(e/1024,0)+" KiB":e=t.formatNumber(e,0)+" bytes",e},t.bytesFromIP=function(e){return e.indexOf(".")!==-1?t.bytesFromIPv4(e):e.indexOf(":")!==-1?t.bytesFromIPv6(e):null},t.bytesFromIPv4=function(e){e=e.split(".");if(e.length!==4)return null;var n=t.createBuffer();for(var r=0;rr[i].end-r[i].start&&(i=r.length-1))}n.push(o)}if(r.length>0){var f=r[i];f.end-f.start>0&&(n.splice(f.start,f.end-f.start+1,""),f.start===0&&n.unshift(""),f.end===7&&n.push(""))}return n.join(":")},t.estimateCores=function(e,n){function i(e,u,a){if(u===0){var f=Math.floor(e.reduce(function(e,t){return e+t},0)/e.length);return t.cores=Math.max(1,f),URL.revokeObjectURL(r),n(null,t.cores)}s(a,function(t,n){e.push(o(a,n)),i(e,u-1,a)})}function s(e,t){var n=[],i=[];for(var s=0;su.st&&i.sti.st&&u.st=this.blockSize||this._input.length()>0&&this._finish)this._op.call(this.mode,this._input,this.output);this._input.compact()},t.prototype.finish=function(e){e&&this.mode.name==="CBC"&&(this.mode.pad=function(t){return e(this.blockSize,t,!1)},this.mode.unpad=function(t){return e(this.blockSize,t,!0)});var t={};return t.overflow=this._input.length()%this.blockSize,!this._decrypt&&this.mode.pad&&!this.mode.pad(this._input,t)?!1:(this._finish=!0,this.update(),this._decrypt&&this.mode.unpad&&!this.mode.unpad(this.output,t)?!1:this.mode.afterFinish&&!this.mode.afterFinish(this.output,t)?!1:!0)}}var r="cipher";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o4){var n=t;t=e.util.createBuffer();for(var r=0;r0)return!1;var n=e.length(),r=e.at(n-1);return r>this.blockSize<<2?!1:(e.truncate(r),!0)},t.cbc=function(e){e=e||{},this.name="CBC",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._blocks=this.blockSize/4,this._inBlock=new Array(this._blocks),this._outBlock=new Array(this._blocks)},t.cbc.prototype.start=function(e){if(e.iv===null){if(!this._prev)throw new Error("Invalid IV parameter.");this._iv=this._prev.slice(0)}else{if(!("iv"in e))throw new Error("Invalid IV parameter.");this._iv=n(e.iv),this._prev=this._iv.slice(0)}},t.cbc.prototype.encrypt=function(e,t){for(var n=0;n0)return!1;var n=e.length(),r=e.at(n-1);return r>this.blockSize<<2?!1:(e.truncate(r),!0)},t.cfb=function(e){e=e||{},this.name="CFB",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._blocks=this.blockSize/4,this._inBlock=null,this._outBlock=new Array(this._blocks)},t.cfb.prototype.start=function(e){if(!("iv"in e))throw new Error("Invalid IV parameter.");this._iv=n(e.iv),this._inBlock=this._iv.slice(0)},t.cfb.prototype.encrypt=function(e,t){this.cipher.encrypt(this._inBlock,this._outBlock);for(var n=0;n0&&e.truncate(this.blockSize-t.overflow),!0},t.ofb=function(e){e=e||{},this.name="OFB",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._blocks=this.blockSize/4,this._inBlock=null,this._outBlock=new Array(this._blocks)},t.ofb.prototype.start=function(e){if(!("iv"in e))throw new Error("Invalid IV parameter.");this._iv=n(e.iv),this._inBlock=this._iv.slice(0)},t.ofb.prototype.encrypt=function(e,t){this.cipher.encrypt(this._inBlock,this._outBlock);for(var n=0;n0&&e.truncate(this.blockSize-t.overflow),!0},t.ctr=function(e){e=e||{},this.name="CTR",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._blocks=this.blockSize/4,this._inBlock=null,this._outBlock=new Array(this._blocks)},t.ctr.prototype.start=function(e){if(!("iv"in e))throw new Error("Invalid IV parameter.");this._iv=n(e.iv),this._inBlock=this._iv.slice(0)},t.ctr.prototype.encrypt=function(e,t){this.cipher.encrypt(this._inBlock,this._outBlock),r(this._inBlock);for(var n=0;n0&&e.truncate(this.blockSize-t.overflow),!0},t.gcm=function(e){e=e||{},this.name="GCM",this.cipher=e.cipher,this.blockSize=e.blockSize||16,this._blocks=this.blockSize/4,this._inBlock=new Array(this._blocks),this._outBlock=new Array(this._blocks),this._R=3774873600},t.gcm.prototype.start=function(t){if(!("iv"in t))throw new Error("Invalid IV parameter.");var n=e.util.createBuffer(t.iv);this._cipherLength=0;var s;"additionalData"in t?s=e.util.createBuffer(t.additionalData):s=e.util.createBuffer(),"tagLength"in t?this._tagLength=t.tagLength:this._tagLength=128,this._tag=e.util.createBuffer(t.tag).getBytes(),this._hashBlock=new Array(this._blocks),this.tag=null,this._hashSubkey=new Array(this._blocks),this.cipher.encrypt([0,0,0,0],this._hashSubkey),this.componentBits=4,this._m=this.generateHashTable(this._hashSubkey,this.componentBits);var o=n.length();if(o===12)this._j0=[n.getInt32(),n.getInt32(),n.getInt32(),1];else{this._j0=[0,0,0,0];while(n.length()>0)this._j0=this.ghash(this._hashSubkey,this._j0,[n.getInt32(),n.getInt32(),n.getInt32(),n.getInt32()]);this._j0=this.ghash(this._hashSubkey,this._j0,[0,0].concat(i(o*8)))}this._inBlock=this._j0.slice(0),r(this._inBlock),s=e.util.createBuffer(s),this._aDataLength=i(s.length()*8);var u=s.length()%this.blockSize;u&&s.fillWithByte(0,this.blockSize-u),this._s=[0,0,0,0];while(s.length()>0)this._s=this.ghash(this._hashSubkey,this._s,[s.getInt32(),s.getInt32(),s.getInt32(),s.getInt32()])},t.gcm.prototype.encrypt=function(t,n){this.cipher.encrypt(this._inBlock,this._outBlock),r(this._inBlock);var i=t.length();for(var s=0;s0;--r)t[r]=e[r]>>>1|(e[r-1]&1)<<31;t[0]=e[0]>>>1,n&&(t[0]^=this._R)},t.gcm.prototype.tableMultiply=function(e){var t=[0,0,0,0];for(var n=0;n<32;++n){var r=n/8|0,i=e[r]>>>(7-n%8)*4&15,s=this._m[n][i];t[0]^=s[0],t[1]^=s[1],t[2]^=s[2],t[3]^=s[3]}return t},t.gcm.prototype.ghash=function(e,t,n){return t[0]^=n[0],t[1]^=n[1],t[2]^=n[2],t[3]^=n[3],this.tableMultiply(t)},t.gcm.prototype.generateHashTable=function(e,t){var n=8/t,r=4*n,i=16*n,s=new Array(i);for(var o=0;o>>1,i=new Array(n);i[r]=e.slice(0);var s=r>>>1;while(s>0)this.pow(i[2*s],i[s]=[]),s>>=1;s=2;while(s>8^p&255^99,i[r]=p,s[p]=r,d=e[p],l=e[r],c=e[l],h=e[c],v=d<<24^p<<16^p<<8^(p^d),m=(l^c^h)<<24^(r^h)<<16^(r^c^h)<<8^(r^l^h);for(var g=0;g<4;++g)u[g][r]=v,a[g][p]=m,v=v<<24|v>>>8,m=m<<24|m>>>8;r===0?r=f=1:(r=l^e[e[e[l^h]]],f^=e[e[f]])}}function l(e,t){var n=e.slice(0),s,u=1,f=n.length,l=f+6+1,c=r*l;for(var h=f;h>>16&255]<<24^i[s>>>8&255]<<16^i[s&255]<<8^i[s>>>24]^o[u]<<24,u++):f>6&&h%f===4&&(s=i[s>>>24]<<24^i[s>>>16&255]<<16^i[s>>>8&255]<<8^i[s&255]),n[h]=n[h-f]^s;if(t){var p,d=a[0],v=a[1],m=a[2],g=a[3],y=n.slice(0);c=n.length;for(var h=0,b=c-r;h>>24]]^v[i[p>>>16&255]]^m[i[p>>>8&255]]^g[i[p&255]];n=y}return n}function c(e,t,n,r){var o=e.length/4-1,f,l,c,h,p;r?(f=a[0],l=a[1],c=a[2],h=a[3],p=s):(f=u[0],l=u[1],c=u[2],h=u[3],p=i);var d,v,m,g,y,b,w;d=t[0]^e[0],v=t[r?3:1]^e[1],m=t[2]^e[2],g=t[r?1:3]^e[3];var E=3;for(var S=1;S>>24]^l[v>>>16&255]^c[m>>>8&255]^h[g&255]^e[++E],b=f[v>>>24]^l[m>>>16&255]^c[g>>>8&255]^h[d&255]^e[++E],w=f[m>>>24]^l[g>>>16&255]^c[d>>>8&255]^h[v&255]^e[++E],g=f[g>>>24]^l[d>>>16&255]^c[v>>>8&255]^h[m&255]^e[++E],d=y,v=b,m=w;n[0]=p[d>>>24]<<24^p[v>>>16&255]<<16^p[m>>>8&255]<<8^p[g&255]^e[++E],n[r?3:1]=p[v>>>24]<<24^p[m>>>16&255]<<16^p[g>>>8&255]<<8^p[d&255]^e[++E],n[2]=p[m>>>24]<<24^p[g>>>16&255]<<16^p[d>>>8&255]<<8^p[v&255]^e[++E],n[r?1:3]=p[g>>>24]<<24^p[d>>>16&255]<<16^p[v>>>8&255]<<8^p[m&255]^e[++E]}function h(t){t=t||{};var n=(t.mode||"CBC").toUpperCase(),r="AES-"+n,i;t.decrypt?i=e.cipher.createDecipher(r,t.key):i=e.cipher.createCipher(r,t.key);var s=i.start;return i.start=function(t,n){var r=null;n instanceof e.util.ByteBuffer&&(r=n,n={}),n=n||{},n.output=r,n.iv=t,s.call(i,n)},i}e.aes=e.aes||{},e.aes.startEncrypting=function(e,t,n,r){var i=h({key:e,output:n,decrypt:!1,mode:r});return i.start(t),i},e.aes.createEncryptionCipher=function(e,t){return h({key:e,output:null,decrypt:!1,mode:t})},e.aes.startDecrypting=function(e,t,n,r){var i=h({key:e,output:n,decrypt:!0,mode:r});return i.start(t),i},e.aes.createDecryptionCipher=function(e,t){return h({key:e,output:null,decrypt:!0,mode:t})},e.aes.Algorithm=function(e,t){n||f();var r=this;r.name=e,r.mode=new t({blockSize:16,cipher:{encrypt:function(e,t){return c(r._w,e,t,!1)},decrypt:function(e,t){return c(r._w,e,t,!0)}}}),r._init=!1},e.aes.Algorithm.prototype.initialize=function(t){if(this._init)return;var n=t.key,r;if(typeof n!="string"||n.length!==16&&n.length!==24&&n.length!==32){if(e.util.isArray(n)&&(n.length===16||n.length===24||n.length===32)){r=n,n=e.util.createBuffer();for(var i=0;i>>=2;for(var i=0;i1){var h=r.read,p=r.getByte();if(p===0){s=r.getByte();var d=s&192;if(d===t.Class.UNIVERSAL||d===t.Class.CONTEXT_SPECIFIC)try{var v=n(r);c=v===a-(r.read-h),c&&(++h,--a)}catch(m){}}r.read=h}if(c){f=[];if(a===undefined)for(;;){if(r.bytes(2)===String.fromCharCode(0,0)){r.getBytes(2);break}f.push(t.fromDer(r,i))}else{var g=r.length();while(a>0)f.push(t.fromDer(r,i)),a-=g-r.length(),g=r.length()}}else{if(a===undefined){if(i)throw{message:"Non-constructed ASN.1 object of indefinite length."};a=r.length()}if(u===t.Type.BMPSTRING){f="";for(var y=0;y>>=8;while(u>0);r.putByte(a.length|128);for(var o=a.length-1;o>=0;--o)r.putByte(a.charCodeAt(o))}return r.putBuffer(s),r},t.oidToDer=function(t){var n=t.split("."),r=e.util.createBuffer();r.putByte(40*parseInt(n[0],10)+parseInt(n[1],10));var i,s,o,u;for(var a=2;a>>=7,i||(u|=128),s.push(u),i=!1;while(o>0);for(var f=s.length-1;f>=0;--f)r.putByte(s[f])}return r},t.derToOid=function(t){var n;typeof t=="string"&&(t=e.util.createBuffer(t));var r=t.getByte();n=Math.floor(r/40)+"."+r%40;var i=0;while(t.length()>0)r=t.getByte(),i<<=7,r&128?i+=r&127:(n+="."+(i+r),i=0);return n},t.utcTimeToDate=function(e){var t=new Date,n=parseInt(e.substr(0,2),10);n=n>=50?1900+n:2e3+n;var r=parseInt(e.substr(2,2),10)-1,i=parseInt(e.substr(4,2),10),s=parseInt(e.substr(6,2),10),o=parseInt(e.substr(8,2),10),u=0;if(e.length>11){var a=e.charAt(10),f=10;a!=="+"&&a!=="-"&&(u=parseInt(e.substr(10,2),10),f+=2)}t.setUTCFullYear(n,r,i),t.setUTCHours(s,o,u,0);if(f){a=e.charAt(f);if(a==="+"||a==="-"){var l=parseInt(e.substr(f+1,2),10),c=parseInt(e.substr(f+4,2),10),h=l*60+c;h*=6e4,a==="+"?t.setTime(+t-h):t.setTime(+t+h)}}return t},t.generalizedTimeToDate=function(e){var t=new Date,n=parseInt(e.substr(0,4),10),r=parseInt(e.substr(4,2),10)-1,i=parseInt(e.substr(6,2),10),s=parseInt(e.substr(8,2),10),o=parseInt(e.substr(10,2),10),u=parseInt(e.substr(12,2),10),a=0,f=0,l=!1;e.charAt(e.length-1)==="Z"&&(l=!0);var c=e.length-5,h=e.charAt(c);if(h==="+"||h==="-"){var p=parseInt(e.substr(c+1,2),10),d=parseInt(e.substr(c+4,2),10);f=p*60+d,f*=6e4,h==="+"&&(f*=-1),l=!0}return e.charAt(14)==="."&&(a=parseFloat(e.substr(14),10)*1e3),l?(t.setUTCFullYear(n,r,i),t.setUTCHours(s,o,u,a),t.setTime(+t+f)):(t.setFullYear(n,r,i),t.setHours(s,o,u,a)),t},t.dateToUtcTime=function(e){var t="",n=[];n.push((""+e.getUTCFullYear()).substr(2)),n.push(""+(e.getUTCMonth()+1)),n.push(""+e.getUTCDate()),n.push(""+e.getUTCHours()),n.push(""+e.getUTCMinutes()),n.push(""+e.getUTCSeconds());for(var r=0;r=-128&&t<128)return n.putSignedInt(t,8);if(t>=-32768&&t<32768)return n.putSignedInt(t,16);if(t>=-8388608&&t<8388608)return n.putSignedInt(t,24);if(t>=-2147483648&&t<2147483648)return n.putSignedInt(t,32);throw{message:"Integer too large; max is 32-bits.",integer:t}},t.derToInteger=function(t){typeof t=="string"&&(t=e.util.createBuffer(t));var n=t.length()*8;if(n>32)throw{message:"Integer too large; max is 32-bits."};return t.getSignedInt(n)},t.validate=function(n,r,i,s){var o=!1;if(n.tagClass!==r.tagClass&&typeof r.tagClass!="undefined"||n.type!==r.type&&typeof r.type!="undefined")s&&(n.tagClass!==r.tagClass&&s.push("["+r.name+"] "+'Expected tag class "'+r.tagClass+'", got "'+n.tagClass+'"'),n.type!==r.type&&s.push("["+r.name+"] "+'Expected type "'+r.type+'", got "'+n.type+'"'));else if(n.constructed===r.constructed||typeof r.constructed=="undefined"){o=!0;if(r.value&&e.util.isArray(r.value)){var u=0;for(var a=0;o&&a0&&(o+="\n");var u="";for(var a=0;a=64){u=e.h0,a=e.h1,f=e.h2,l=e.h3;for(p=0;p<16;++p)t[p]=n.getInt32Le(),c=l^a&(f^l),o=u+c+s[p]+t[p],h=i[p],u=l,l=f,f=a,a+=o<>>32-h;for(;p<32;++p)c=f^l&(a^f),o=u+c+s[p]+t[r[p]],h=i[p],u=l,l=f,f=a,a+=o<>>32-h;for(;p<48;++p)c=a^f^l,o=u+c+s[p]+t[r[p]],h=i[p],u=l,l=f,f=a,a+=o<>>32-h;for(;p<64;++p)c=f^(a|~l),o=u+c+s[p]+t[r[p]],h=i[p],u=l,l=f,f=a,a+=o<>>32-h;e.h0=e.h0+u|0,e.h1=e.h1+a|0,e.h2=e.h2+f|0,e.h3=e.h3+l|0,d-=64}}var t=e.md5=e.md5||{};e.md=e.md||{},e.md.algorithms=e.md.algorithms||{},e.md.md5=e.md.algorithms.md5=t,t.create=function(){o||u();var t=null,r=e.util.createBuffer(),i=new Array(16),s={algorithm:"md5",blockLength:64,digestLength:16,messageLength:0,messageLength64:[0,0]};return s.start=function(){return s.messageLength=0,s.messageLength64=[0,0],r=e.util.createBuffer(),t={h0:1732584193,h1:4023233417,h2:2562383102,h3:271733878},s},s.start(),s.update=function(n,o){return o==="utf8"&&(n=e.util.encodeUtf8(n)),s.messageLength+=n.length,s.messageLength64[0]+=n.length/4294967296>>>0,s.messageLength64[1]+=n.length>>>0,r.putBytes(n),a(t,i,r),(r.read>2048||r.length()===0)&&r.compact(),s},s.digest=function(){var o=e.util.createBuffer();o.putBytes(r.bytes()),o.putBytes(n.substr(0,64-(s.messageLength64[1]+8&63))),o.putInt32Le(s.messageLength64[1]<<3),o.putInt32Le(s.messageLength64[0]<<3|s.messageLength64[0]>>>28);var u={h0:t.h0,h1:t.h1,h2:t.h2,h3:t.h3};a(u,i,o);var f=e.util.createBuffer();return f.putInt32Le(u.h0),f.putInt32Le(u.h1),f.putInt32Le(u.h2),f.putInt32Le(u.h3),f},s};var n=null,r=null,i=null,s=null,o=!1}var r="md5";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=64){i=e.h0,s=e.h1,o=e.h2,u=e.h3,a=e.h4;for(l=0;l<16;++l)r=n.getInt32(),t[l]=r,f=u^s&(o^u),r=(i<<5|i>>>27)+f+a+1518500249+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<20;++l)r=t[l-3]^t[l-8]^t[l-14]^t[l-16],r=r<<1|r>>>31,t[l]=r,f=u^s&(o^u),r=(i<<5|i>>>27)+f+a+1518500249+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<32;++l)r=t[l-3]^t[l-8]^t[l-14]^t[l-16],r=r<<1|r>>>31,t[l]=r,f=s^o^u,r=(i<<5|i>>>27)+f+a+1859775393+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<40;++l)r=t[l-6]^t[l-16]^t[l-28]^t[l-32],r=r<<2|r>>>30,t[l]=r,f=s^o^u,r=(i<<5|i>>>27)+f+a+1859775393+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<60;++l)r=t[l-6]^t[l-16]^t[l-28]^t[l-32],r=r<<2|r>>>30,t[l]=r,f=s&o|u&(s^o),r=(i<<5|i>>>27)+f+a+2400959708+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;for(;l<80;++l)r=t[l-6]^t[l-16]^t[l-28]^t[l-32],r=r<<2|r>>>30,t[l]=r,f=s^o^u,r=(i<<5|i>>>27)+f+a+3395469782+r,a=u,u=o,o=s<<30|s>>>2,s=i,i=r;e.h0=e.h0+i|0,e.h1=e.h1+s|0,e.h2=e.h2+o|0,e.h3=e.h3+u|0,e.h4=e.h4+a|0,c-=64}}var t=e.sha1=e.sha1||{};e.md=e.md||{},e.md.algorithms=e.md.algorithms||{},e.md.sha1=e.md.algorithms.sha1=t,t.create=function(){r||i();var t=null,o=e.util.createBuffer(),u=new Array(80),a={algorithm:"sha1",blockLength:64,digestLength:20,messageLength:0,messageLength64:[0,0]};return a.start=function(){return a.messageLength=0,a.messageLength64=[0,0],o=e.util.createBuffer(),t={h0:1732584193,h1:4023233417,h2:2562383102,h3:271733878,h4:3285377520},a},a.start(),a.update=function(n,r){return r==="utf8"&&(n=e.util.encodeUtf8(n)),a.messageLength+=n.length,a.messageLength64[0]+=n.length/4294967296>>>0,a.messageLength64[1]+=n.length>>>0,o.putBytes(n),s(t,u,o),(o.read>2048||o.length()===0)&&o.compact(),a},a.digest=function(){var r=e.util.createBuffer();r.putBytes(o.bytes()),r.putBytes(n.substr(0,64-(a.messageLength64[1]+8&63))),r.putInt32(a.messageLength64[0]<<3|a.messageLength64[0]>>>28),r.putInt32(a.messageLength64[1]<<3);var i={h0:t.h0,h1:t.h1,h2:t.h2,h3:t.h3,h4:t.h4};s(i,u,r);var f=e.util.createBuffer();return f.putInt32(i.h0),f.putInt32(i.h1),f.putInt32(i.h2),f.putInt32(i.h3),f.putInt32(i.h4),f},a};var n=null,r=!1}var r="sha1";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=64){for(l=0;l<16;++l)t[l]=n.getInt32();for(;l<64;++l)r=t[l-2],r=(r>>>17|r<<15)^(r>>>19|r<<13)^r>>>10,s=t[l-15],s=(s>>>7|s<<25)^(s>>>18|s<<14)^s>>>3,t[l]=r+t[l-7]+s+t[l-16]|0;c=e.h0,h=e.h1,p=e.h2,d=e.h3,v=e.h4,m=e.h5,g=e.h6,y=e.h7;for(l=0;l<64;++l)u=(v>>>6|v<<26)^(v>>>11|v<<21)^(v>>>25|v<<7),a=g^v&(m^g),o=(c>>>2|c<<30)^(c>>>13|c<<19)^(c>>>22|c<<10),f=c&h|p&(c^h),r=y+u+a+i[l]+t[l],s=o+f,y=g,g=m,m=v,v=d+r|0,d=p,p=h,h=c,c=r+s|0;e.h0=e.h0+c|0,e.h1=e.h1+h|0,e.h2=e.h2+p|0,e.h3=e.h3+d|0,e.h4=e.h4+v|0,e.h5=e.h5+m|0,e.h6=e.h6+g|0,e.h7=e.h7+y|0,b-=64}}var t=e.sha256=e.sha256||{};e.md=e.md||{},e.md.algorithms=e.md.algorithms||{},e.md.sha256=e.md.algorithms.sha256=t,t.create=function(){r||s();var t=null,i=e.util.createBuffer(),u=new Array(64),a={algorithm:"sha256",blockLength:64,digestLength:32,messageLength:0,messageLength64:[0,0]};return a.start=function(){return a.messageLength=0,a.messageLength64=[0,0],i=e.util.createBuffer(),t={h0:1779033703,h1:3144134277,h2:1013904242,h3:2773480762,h4:1359893119,h5:2600822924,h6:528734635,h7:1541459225},a},a.start(),a.update=function(n,r){return r==="utf8"&&(n=e.util.encodeUtf8(n)),a.messageLength+=n.length,a.messageLength64[0]+=n.length/4294967296>>>0,a.messageLength64[1]+=n.length>>>0,i.putBytes(n),o(t,u,i),(i.read>2048||i.length()===0)&&i.compact(),a},a.digest=function(){var r=e.util.createBuffer();r.putBytes(i.bytes()),r.putBytes(n.substr(0,64-(a.messageLength64[1]+8&63))),r.putInt32(a.messageLength64[0]<<3|a.messageLength64[0]>>>28),r.putInt32(a.messageLength64[1]<<3);var s={h0:t.h0,h1:t.h1,h2:t.h2,h3:t.h3,h4:t.h4,h5:t.h5,h6:t.h6,h7:t.h7};o(s,u,r);var f=e.util.createBuffer();return f.putInt32(s.h0),f.putInt32(s.h1),f.putInt32(s.h2),f.putInt32(s.h3),f.putInt32(s.h4),f.putInt32(s.h5),f.putInt32(s.h6),f.putInt32(s.h7),f},a};var n=null,r=!1,i=null}var r="sha256";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=128){for(_=0;_<16;++_)t[_][0]=n.getInt32()>>>0,t[_][1]=n.getInt32()>>>0;for(;_<80;++_)H=t[_-2],D=H[0],P=H[1],r=((D>>>19|P<<13)^(P>>>29|D<<3)^D>>>6)>>>0,i=((D<<13|P>>>19)^(P<<3|D>>>29)^(D<<26|P>>>6))>>>0,j=t[_-15],D=j[0],P=j[1],o=((D>>>1|P<<31)^(D>>>8|P<<24)^D>>>7)>>>0,u=((D<<31|P>>>1)^(D<<24|P>>>8)^(D<<25|P>>>7))>>>0,B=t[_-7],F=t[_-16],P=i+B[1]+u+F[1],t[_][0]=r+B[0]+o+F[0]+(P/4294967296>>>0)>>>0,t[_][1]=P>>>0;m=e[0][0],g=e[0][1],y=e[1][0],b=e[1][1],w=e[2][0],E=e[2][1],S=e[3][0],x=e[3][1],T=e[4][0],N=e[4][1],C=e[5][0],k=e[5][1],L=e[6][0],A=e[6][1],O=e[7][0],M=e[7][1];for(_=0;_<80;++_)l=((T>>>14|N<<18)^(T>>>18|N<<14)^(N>>>9|T<<23))>>>0,c=((T<<18|N>>>14)^(T<<14|N>>>18)^(N<<23|T>>>9))>>>0,h=(L^T&(C^L))>>>0,p=(A^N&(k^A))>>>0,a=((m>>>28|g<<4)^(g>>>2|m<<30)^(g>>>7|m<<25))>>>0,f=((m<<4|g>>>28)^(g<<30|m>>>2)^(g<<25|m>>>7))>>>0,d=(m&y|w&(m^y))>>>0,v=(g&b|E&(g^b))>>>0,P=M+c+p+s[_][1]+t[_][1],r=O+l+h+s[_][0]+t[_][0]+(P/4294967296>>>0)>>>0,i=P>>>0,P=f+v,o=a+d+(P/4294967296>>>0)>>>0,u=P>>>0,O=L,M=A,L=C,A=k,C=T,k=N,P=x+i,T=S+r+(P/4294967296>>>0)>>>0,N=P>>>0,S=w,x=E,w=y,E=b,y=m,b=g,P=i+u,m=r+o+(P/4294967296>>>0)>>>0,g=P>>>0;P=e[0][1]+g,e[0][0]=e[0][0]+m+(P/4294967296>>>0)>>>0,e[0][1]=P>>>0,P=e[1][1]+b,e[1][0]=e[1][0]+y+(P/4294967296>>>0)>>>0,e[1][1]=P>>>0,P=e[2][1]+E,e[2][0]=e[2][0]+w+(P/4294967296>>>0)>>>0,e[2][1]=P>>>0,P=e[3][1]+x,e[3][0]=e[3][0]+S+(P/4294967296>>>0)>>>0,e[3][1]=P>>>0,P=e[4][1]+N,e[4][0]=e[4][0]+T+(P/4294967296>>>0)>>>0,e[4][1]=P>>>0,P=e[5][1]+k,e[5][0]=e[5][0]+C+(P/4294967296>>>0)>>>0,e[5][1]=P>>>0,P=e[6][1]+A,e[6][0]=e[6][0]+L+(P/4294967296>>>0)>>>0,e[6][1]=P>>>0,P=e[7][1]+M,e[7][0]=e[7][0]+O+(P/4294967296>>>0)>>>0,e[7][1]=P>>>0,I-=128}}var t=e.sha512=e.sha512||{};e.md=e.md||{},e.md.algorithms=e.md.algorithms||{},e.md.sha512=e.md.algorithms.sha512=t;var n=e.sha384=e.sha512.sha384=e.sha512.sha384||{};n.create=function(){return t.create("SHA-384")},e.md.sha384=e.md.algorithms.sha384=n,e.sha512.sha256=e.sha512.sha256||{create:function(){return t.create("SHA-512/256")}},e.md["sha512/256"]=e.md.algorithms["sha512/256"]=e.sha512.sha256,e.sha512.sha224=e.sha512.sha224||{create:function(){return t.create("SHA-512/224")}},e.md["sha512/224"]=e.md.algorithms["sha512/224"]=e.sha512.sha224,t.create=function(t){i||u(),typeof t=="undefined"&&(t="SHA-512");if(t in o){var n=o[t],s=null,f=e.util.createBuffer(),l=new Array(80);for(var c=0;c<80;++c)l[c]=new Array(2);var h={algorithm:t.replace("-","").toLowerCase(),blockLength:128,digestLength:64,messageLength:0,messageLength128:[0,0,0,0]};return h.start=function(){h.messageLength=0,h.messageLength128=[0,0,0,0],f=e.util.createBuffer(),s=new Array(n.length);for(var t=0;t>>0,r>>>0];for(var i=3;i>=0;--i)h.messageLength128[i]+=r[1],r[1]=r[0]+(h.messageLength128[i]/4294967296>>>0),h.messageLength128[i]=h.messageLength128[i]>>>0,r[0]=r[1]/4294967296>>>0;return f.putBytes(t),a(s,l,f),(f.read>2048||f.length()===0)&&f.compact(),h},h.digest=function(){var n=e.util.createBuffer();n.putBytes(f.bytes()),n.putBytes(r.substr(0,128-(h.messageLength128[3]+16&127)));var i=[];for(var o=0;o<3;++o)i[o]=h.messageLength128[o]<<3|h.messageLength128[o-1]>>>28;i[3]=h.messageLength128[3]<<3,n.putInt32(i[0]),n.putInt32(i[1]),n.putInt32(i[2]),n.putInt32(i[3]);var u=new Array(s.length);for(var o=0;on.blockLength&&(n.start(),n.update(o.bytes()),o=n.digest()),r=e.util.createBuffer(),i=e.util.createBuffer(),f=o.length();for(var a=0;a65&&o!==-1){var u=t[o];u===","?(++o,t=t.substr(0,o)+"\r\n "+t.substr(o)):t=t.substr(0,o)+"\r\n"+u+t.substr(o+1),s=i-o-1,o=-1,++i}else if(t[i]===" "||t[i]===" "||t[i]===",")o=i;return t}function r(e){return e.replace(/^\s+/,"")}var t=e.pem=e.pem||{};t.encode=function(t,r){r=r||{};var i="-----BEGIN "+t.type+"-----\r\n",s;t.procType&&(s={name:"Proc-Type",values:[String(t.procType.version),t.procType.type]},i+=n(s)),t.contentDomain&&(s={name:"Content-Domain",values:[t.contentDomain]},i+=n(s)),t.dekInfo&&(s={name:"DEK-Info",values:[t.dekInfo.algorithm]},t.dekInfo.parameters&&s.values.push(t.dekInfo.parameters),i+=n(s));if(t.headers)for(var o=0;o8?3:1,m=[],g=[0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0],y=0,b;for(var w=0;w>>4^S)&252645135,S^=b,E^=b<<4,b=(S>>>-16^E)&65535,E^=b,S^=b<<-16,b=(E>>>2^S)&858993459,S^=b,E^=b<<2,b=(S>>>-16^E)&65535,E^=b,S^=b<<-16,b=(E>>>1^S)&1431655765,S^=b,E^=b<<1,b=(S>>>8^E)&16711935,E^=b,S^=b<<8,b=(E>>>1^S)&1431655765,S^=b,E^=b<<1,b=E<<8|S>>>20&240,E=S<<24|S<<8&16711680|S>>>8&65280|S>>>24&240,S=b;for(var x=0;x>>26,S=S<<2|S>>>26):(E=E<<1|E>>>27,S=S<<1|S>>>27),E&=-15,S&=-15;var T=t[E>>>28]|n[E>>>24&15]|r[E>>>20&15]|i[E>>>16&15]|s[E>>>12&15]|o[E>>>8&15]|u[E>>>4&15],N=a[S>>>28]|f[S>>>24&15]|l[S>>>20&15]|c[S>>>16&15]|h[S>>>12&15]|p[S>>>8&15]|d[S>>>4&15];b=(N>>>16^T)&65535,m[y++]=T^b,m[y++]=N^b<<16}}return m}function c(e,t,l,c){var h=e.length===32?3:9,p;h===3?p=c?[30,-2,-2]:[0,32,2]:p=c?[94,62,-2,32,64,2,30,-2,-2]:[0,32,2,62,30,-2,64,96,2];var d,v=t[0],m=t[1];d=(v>>>4^m)&252645135,m^=d,v^=d<<4,d=(v>>>16^m)&65535,m^=d,v^=d<<16,d=(m>>>2^v)&858993459,v^=d,m^=d<<2,d=(m>>>8^v)&16711935,v^=d,m^=d<<8,d=(v>>>1^m)&1431655765,m^=d,v^=d<<1,v=v<<1|v>>>31,m=m<<1|m>>>31;for(var g=0;g>>4|m<<28)^e[w+1];d=v,v=m,m=d^(r[E>>>24&63]|s[E>>>16&63]|u[E>>>8&63]|f[E&63]|n[S>>>24&63]|i[S>>>16&63]|o[S>>>8&63]|a[S&63])}d=v,v=m,m=d}v=v>>>1|v<<31,m=m>>>1|m<<31,d=(v>>>1^m)&1431655765,m^=d,v^=d<<1,d=(m>>>8^v)&16711935,v^=d,m^=d<<8,d=(m>>>2^v)&858993459,v^=d,m^=d<<2,d=(v>>>16^m)&65535,m^=d,v^=d<<16,d=(v>>>4^m)&252645135,m^=d,v^=d<<4,l[0]=v,l[1]=m}function h(t){t=t||{};var n=(t.mode||"CBC").toUpperCase(),r="DES-"+n,i;t.decrypt?i=e.cipher.createDecipher(r,t.key):i=e.cipher.createCipher(r,t.key);var s=i.start;return i.start=function(t,n){var r=null;n instanceof e.util.ByteBuffer&&(r=n,n={}),n=n||{},n.output=r,n.iv=t,s.call(i,n)},i}e.des=e.des||{},e.des.startEncrypting=function(e,t,n,r){var i=h({key:e,output:n,decrypt:!1,mode:r||(t===null?"ECB":"CBC")});return i.start(t),i},e.des.createEncryptionCipher=function(e,t){return h({key:e,output:null,decrypt:!1,mode:t})},e.des.startDecrypting=function(e,t,n,r){var i=h({key:e,output:n,decrypt:!0,mode:r||(t===null?"ECB":"CBC")});return i.start(t),i},e.des.createDecryptionCipher=function(e,t){return h({key:e,output:null,decrypt:!0,mode:t})},e.des.Algorithm=function(e,t){var n=this;n.name=e,n.mode=new t({blockSize:8,cipher:{encrypt:function(e,t){return c(n._keys,e,t,!1)},decrypt:function(e,t){return c(n._keys,e,t,!0)}}}),n._init=!1},e.des.Algorithm.prototype.initialize=function(t){if(this._init)return;var n=e.util.createBuffer(t.key);if(this.name.indexOf("3DES")===0&&n.length()!==24)throw new Error("Invalid Triple-DES key size: "+n.length()*8);this._keys=l(n),this._init=!0},t("DES-ECB",e.cipher.modes.ecb),t("DES-CBC",e.cipher.modes.cbc),t("DES-CFB",e.cipher.modes.cfb),t("DES-OFB",e.cipher.modes.ofb),t("DES-CTR",e.cipher.modes.ctr),t("3DES-ECB",e.cipher.modes.ecb),t("3DES-CBC",e.cipher.modes.cbc),t("3DES-CFB",e.cipher.modes.cfb),t("3DES-OFB",e.cipher.modes.ofb),t("3DES-CTR",e.cipher.modes.ctr);var n=[16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028,16778240,16778240,0,65540,66560,0,16842756],r=[-2146402272,-2147450880,32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576,-2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880,32800,-2147483648,-2146435040,-2146402272,1081344],i=[520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072,134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800,131592,8,134348808,131584],s=[8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928],o=[256,34078976,34078720,1107296512,524288,256,1073741824,34078720,1074266368,524288,33554688,1074266368,1107296512,1107820544,524544,1073741824,33554432,1074266112,1074266112,0,1073742080,1107820800,1107820800,33554688,1107820544,1073742080,0,1107296256,34078976,33554432,1107296256,524544,524288,1107296512,256,33554432,1073741824,34078720,1107296512,1074266368,33554688,1073741824,1107820544,34078976,1074266368,256,33554432,1107820544,1107820800,524544,1107296256,1107820800,34078720,0,1074266112,1107296256,524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080],u=[536870928,541065216,16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384,541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312],a=[2097152,69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066,0,2099202,69206016,2048,67108866,67110912,2048,2097154],f=[268439616,4096,262144,268701760,268435456,268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240,266240,4160,4160,262208,268435456,268701696]}var r="des";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o4294967295*o)throw{message:"Derived key is too long."};var u=Math.ceil(i/o),a=i-(u-1)*o,f=e.hmac.create();f.start(s,t);var l="",c,h,p;for(var d=1;d<=u;++d){f.start(null,null),f.update(n),f.update(e.util.int32ToBytes(d)),c=p=f.digest().getBytes();for(var v=2;v<=r;++v)f.start(null,null),f.update(p),h=f.digest().getBytes(),c=e.util.xorBytes(c,h,o),p=h;l+=d=32)return f(),e();var t=32-n.pools[0].messageLength<<5;n.seedFile(t,function(t,r){if(t)return e(t);n.collect(r),f(),e()})}function a(){if(n.pools[0].messageLength>=32)return f();var e=32-n.pools[0].messageLength<<5;n.collect(n.seedFileSync(e)),f()}function f(){var e=n.plugin.md.create();e.update(n.pools[0].digest().getBytes()),n.pools[0].start();var t=1;for(var r=1;r<32;++r)t=t===31?2147483648:t<<2,t%n.reseeds===0&&(e.update(n.pools[r].digest().getBytes()),n.pools[r].start());var i=e.digest().getBytes();e.start(),e.update(i);var s=e.digest().getBytes();n.key=n.plugin.formatKey(i),n.seed=n.plugin.formatSeed(s),n.reseeds=n.reseeds===4294967295?0:n.reseeds+1,n.generated=0}function l(t){var n=null;if(typeof window!="undefined"){var r=window.crypto||window.msCrypto;r&&r.getRandomValues&&(n=function(e){return r.getRandomValues(e)})}var i=e.util.createBuffer();if(n)while(i.length()>16),l+=(f&32767)<<16,l+=f>>15,l=(l&2147483647)+(l>>31),h=l&4294967295;for(var u=0;u<3;++u)c=h>>>(u<<3),c^=Math.floor(Math.random()*256),i.putByte(String.fromCharCode(c&255))}}return i.getBytes(t)}var n={plugin:t,key:null,seed:null,time:null,reseeds:0,generated:0},i=t.md,s=new Array(32);for(var o=0;o<32;++o)s[o]=i.create();return n.pools=s,n.pool=0,n.generate=function(t,r){function l(c){if(c)return r(c);if(f.length()>=t)return r(null,f.getBytes(t));n.generated>1048575&&(n.key=null);if(n.key===null)return e.util.nextTick(function(){u(l)});var h=i(n.key,n.seed);n.generated+=h.length,f.putBytes(h),n.key=o(i(n.key,s(n.seed))),n.seed=a(i(n.key,n.seed)),e.util.setImmediate(l)}if(!r)return n.generateSync(t);var i=n.plugin.cipher,s=n.plugin.increment,o=n.plugin.formatKey,a=n.plugin.formatSeed,f=e.util.createBuffer();n.key=null,l()},n.generateSync=function(t){var r=n.plugin.cipher,i=n.plugin.increment,s=n.plugin.formatKey,o=n.plugin.formatSeed;n.key=null;var u=e.util.createBuffer();while(u.length()1048575&&(n.key=null),n.key===null&&a();var f=r(n.key,n.seed);n.generated+=f.length,u.putBytes(f),n.key=s(r(n.key,i(n.seed))),n.seed=o(r(n.key,n.seed))}return u.getBytes(t)},r?(n.seedFile=function(e,t){r.randomBytes(e,function(e,n){if(e)return t(e);t(null,n.toString())})},n.seedFileSync=function(e){return r.randomBytes(e).toString()}):(n.seedFile=function(e,t){try{t(null,l(e))}catch(n){t(n)}},n.seedFileSync=l),n.collect=function(e){var t=e.length;for(var r=0;r>i&255);n.collect(r)},n.registerWorker=function(e){if(e===self)n.seedFile=function(e,t){function n(e){var r=e.data;r.forge&&r.forge.prng&&(self.removeEventListener("message",n),t(r.forge.prng.err,r.forge.prng.bytes))}self.addEventListener("message",n),self.postMessage({forge:{prng:{needed:e}}})};else{var t=function(t){var r=t.data;r.forge&&r.forge.prng&&n.seedFile(r.forge.prng.needed,function(t,n){e.postMessage({forge:{prng:{err:t,bytes:n}}})})};e.addEventListener("message",t)}},n}}var r="prng";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o>16-t},i=function(e,t){return(e&65535)>>t|e<<16-t&65535};e.rc2=e.rc2||{},e.rc2.expandKey=function(n,r){typeof n=="string"&&(n=e.util.createBuffer(n)),r=r||128;var i=n,s=n.length(),o=r,u=Math.ceil(o/8),a=255>>(o&7),f;for(f=s;f<128;f++)i.putByte(t[i.at(f-1)+i.at(f-s)&255]);i.setAt(128-u,t[i.at(128-u)&a]);for(f=127-u;f>=0;f--)i.setAt(f,t[i.at(f+1)^i.at(f+u)]);return i};var s=function(t,s,o){var u=!1,a=null,f=null,l=null,c,h,p,d,v=[];t=e.rc2.expandKey(t,s);for(p=0;p<64;p++)v.push(t.getInt16Le());o?(c=function(e){for(p=0;p<4;p++)e[p]+=v[d]+(e[(p+3)%4]&e[(p+2)%4])+(~e[(p+3)%4]&e[(p+1)%4]),e[p]=r(e[p],n[p]),d++},h=function(e){for(p=0;p<4;p++)e[p]+=v[e[(p+3)%4]&63]}):(c=function(e){for(p=3;p>=0;p--)e[p]=i(e[p],n[p]),e[p]-=v[d]+(e[(p+3)%4]&e[(p+2)%4])+(~e[(p+3)%4]&e[(p+1)%4]),d--},h=function(e){for(p=3;p>=0;p--)e[p]-=v[e[(p+3)%4]&63]});var m=function(e){var t=[];for(p=0;p<4;p++){var n=a.getInt16Le();l!==null&&(o?n^=l.getInt16Le():l.putInt16Le(n)),t.push(n&65535)}d=o?0:63;for(var r=0;r=8)m([[5,c],[1,h],[6,c],[1,h],[5,c]])},finish:function(e){var t=!0;if(o)if(e)t=e(8,a,!o);else{var n=a.length()===8?8:8-a.length();a.fillWithByte(n,n)}t&&(u=!0,g.update());if(!o){t=a.length()===0;if(t)if(e)t=e(8,f,!o);else{var r=f.length(),i=f.at(r-1);i>r?t=!1:f.truncate(i)}}return t}},g};e.rc2.startEncrypting=function(t,n,r){var i=e.rc2.createEncryptionCipher(t,128);return i.start(n,r),i},e.rc2.createEncryptionCipher=function(e,t){return s(e,t,!0)},e.rc2.startDecrypting=function(t,n,r){var i=e.rc2.createDecryptionCipher(t,128);return i.start(n,r),i},e.rc2.createDecryptionCipher=function(e,t){return s(e,t,!1)}}var r="rc2";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=0){var o=t*this.data[e++]+n.data[r]+i;i=Math.floor(o/67108864),n.data[r++]=o&67108863}return i}function u(e,t,n,r,i,s){var o=t&32767,u=t>>15;while(--s>=0){var a=this.data[e]&32767,f=this.data[e++]>>15,l=u*a+f*o;a=o*a+((l&32767)<<15)+n.data[r]+(i&1073741823),i=(a>>>30)+(l>>>15)+u*f+(i>>>30),n.data[r++]=a&1073741823}return i}function a(e,t,n,r,i,s){var o=t&16383,u=t>>14;while(--s>=0){var a=this.data[e]&16383,f=this.data[e++]>>14,l=u*a+f*o;a=o*a+((l&16383)<<14)+n.data[r]+i,i=(a>>28)+(l>>14)+u*f,n.data[r++]=a&268435455}return i}function d(e){return l.charAt(e)}function v(e,t){var n=c[e.charCodeAt(t)];return n==null?-1:n}function m(e){for(var t=this.t-1;t>=0;--t)e.data[t]=this.data[t];e.t=this.t,e.s=this.s}function g(e){this.t=1,this.s=e<0?-1:0,e>0?this.data[0]=e:e<-1?this.data[0]=e+this.DV:this.t=0}function y(e){var t=s();return t.fromInt(e),t}function b(e,t){var n;if(t==16)n=4;else if(t==8)n=3;else if(t==256)n=8;else if(t==2)n=1;else if(t==32)n=5;else{if(t!=4){this.fromRadix(e,t);return}n=2}this.t=0,this.s=0;var r=e.length,s=!1,o=0;while(--r>=0){var u=n==8?e[r]&255:v(e,r);if(u<0){e.charAt(r)=="-"&&(s=!0);continue}s=!1,o==0?this.data[this.t++]=u:o+n>this.DB?(this.data[this.t-1]|=(u&(1<>this.DB-o):this.data[this.t-1]|=u<=this.DB&&(o-=this.DB)}n==8&&(e[0]&128)!=0&&(this.s=-1,o>0&&(this.data[this.t-1]|=(1<0&&this.data[this.t-1]==e)--this.t}function E(e){if(this.s<0)return"-"+this.negate().toString(e);var t;if(e==16)t=4;else if(e==8)t=3;else if(e==2)t=1;else if(e==32)t=5;else{if(e!=4)return this.toRadix(e);t=2}var n=(1<0){u>u)>0&&(i=!0,s=d(r));while(o>=0)u>(u+=this.DB-t)):(r=this.data[o]>>(u-=t)&n,u<=0&&(u+=this.DB,--o)),r>0&&(i=!0),i&&(s+=d(r))}return i?s:"0"}function S(){var e=s();return i.ZERO.subTo(this,e),e}function x(){return this.s<0?this.negate():this}function T(e){var t=this.s-e.s;if(t!=0)return t;var n=this.t;t=n-e.t;if(t!=0)return this.s<0?-t:t;while(--n>=0)if((t=this.data[n]-e.data[n])!=0)return t;return 0}function N(e){var t=1,n;return(n=e>>>16)!=0&&(e=n,t+=16),(n=e>>8)!=0&&(e=n,t+=8),(n=e>>4)!=0&&(e=n,t+=4),(n=e>>2)!=0&&(e=n,t+=2),(n=e>>1)!=0&&(e=n,t+=1),t}function C(){return this.t<=0?0:this.DB*(this.t-1)+N(this.data[this.t-1]^this.s&this.DM)}function k(e,t){var n;for(n=this.t-1;n>=0;--n)t.data[n+e]=this.data[n];for(n=e-1;n>=0;--n)t.data[n]=0;t.t=this.t+e,t.s=this.s}function L(e,t){for(var n=e;n=0;--u)t.data[u+s+1]=this.data[u]>>r|o,o=(this.data[u]&i)<=0;--u)t.data[u]=0;t.data[s]=o,t.t=this.t+s+1,t.s=this.s,t.clamp()}function O(e,t){t.s=this.s;var n=Math.floor(e/this.DB);if(n>=this.t){t.t=0;return}var r=e%this.DB,i=this.DB-r,s=(1<>r;for(var o=n+1;o>r;r>0&&(t.data[this.t-n-1]|=(this.s&s)<>=this.DB;if(e.t>=this.DB;r+=this.s}else{r+=this.s;while(n>=this.DB;r-=e.s}t.s=r<0?-1:0,r<-1?t.data[n++]=this.DV+r:r>0&&(t.data[n++]=r),t.t=n,t.clamp()}function _(e,t){var n=this.abs(),r=e.abs(),s=n.t;t.t=s+r.t;while(--s>=0)t.data[s]=0;for(s=0;s=0)e.data[n]=0;for(n=0;n=t.DV&&(e.data[n+t.t]-=t.DV,e.data[n+t.t+1]=1)}e.t>0&&(e.data[e.t-1]+=t.am(n,t.data[n],e,2*n,0,1)),e.s=0,e.clamp()}function P(e,t,n){var r=e.abs();if(r.t<=0)return;var o=this.abs();if(o.t0?(r.lShiftTo(l,u),o.lShiftTo(l,n)):(r.copyTo(u),o.copyTo(n));var c=u.t,h=u.data[c-1];if(h==0)return;var p=h*(1<1?u.data[c-2]>>this.F2:0),d=this.FV/p,v=(1<=0&&(n.data[n.t++]=1,n.subTo(b,n)),i.ONE.dlShiftTo(c,b),b.subTo(u,u);while(u.t=0){var w=n.data[--g]==h?this.DM:Math.floor(n.data[g]*d+(n.data[g-1]+m)*v);if((n.data[g]+=u.am(0,w,n,y,0,c))0&&n.rShiftTo(l,n),a<0&&i.ZERO.subTo(n,n)}function H(e){var t=s();return this.abs().divRemTo(e,null,t),this.s<0&&t.compareTo(i.ZERO)>0&&e.subTo(t,t),t}function B(e){this.m=e}function j(e){return e.s<0||e.compareTo(this.m)>=0?e.mod(this.m):e}function F(e){return e}function I(e){e.divRemTo(this.m,null,e)}function q(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function R(e,t){e.squareTo(t),this.reduce(t)}function U(){if(this.t<1)return 0;var e=this.data[0];if((e&1)==0)return 0;var t=e&3;return t=t*(2-(e&15)*t)&15,t=t*(2-(e&255)*t)&255,t=t*(2-((e&65535)*t&65535))&65535,t=t*(2-e*t%this.DV)%this.DV,t>0?this.DV-t:-t}function z(e){this.m=e,this.mp=e.invDigit(),this.mpl=this.mp&32767,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(t,t),t}function X(e){var t=s();return e.copyTo(t),this.reduce(t),t}function V(e){while(e.t<=this.mt2)e.data[e.t++]=0;for(var t=0;t>15)*this.mpl&this.um)<<15)&e.DM;n=t+this.m.t,e.data[n]+=this.m.am(0,r,e,t,0,this.m.t);while(e.data[n]>=e.DV)e.data[n]-=e.DV,e.data[++n]++}e.clamp(),e.drShiftTo(this.m.t,e),e.compareTo(this.m)>=0&&e.subTo(this.m,e)}function $(e,t){e.squareTo(t),this.reduce(t)}function J(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function K(){return(this.t>0?this.data[0]&1:this.s)==0}function Q(e,t){if(e>4294967295||e<1)return i.ONE;var n=s(),r=s(),o=t.convert(this),u=N(e)-1;o.copyTo(n);while(--u>=0){t.sqrTo(n,r);if((e&1<0)t.mulTo(r,o,n);else{var a=n;n=r,r=a}}return t.revert(n)}function G(e,t){var n;return e<256||t.isEven()?n=new B(t):n=new z(t),this.exp(e,n)}function Y(){var e=s();return this.copyTo(e),e}function Z(){if(this.s<0){if(this.t==1)return this.data[0]-this.DV;if(this.t==0)return-1}else{if(this.t==1)return this.data[0];if(this.t==0)return 0}return(this.data[1]&(1<<32-this.DB)-1)<>24}function tt(){return this.t==0?this.s:this.data[0]<<16>>16}function nt(e){return Math.floor(Math.LN2*this.DB/Math.log(e))}function rt(){return this.s<0?-1:this.t<=0||this.t==1&&this.data[0]<=0?0:1}function it(e){e==null&&(e=10);if(this.signum()==0||e<2||e>36)return"0";var t=this.chunkSize(e),n=Math.pow(e,t),r=y(n),i=s(),o=s(),u="";this.divRemTo(r,i,o);while(i.signum()>0)u=(n+o.intValue()).toString(e).substr(1)+u,i.divRemTo(r,i,o);return o.intValue().toString(e)+u}function st(e,t){this.fromInt(0),t==null&&(t=10);var n=this.chunkSize(t),r=Math.pow(t,n),s=!1,o=0,u=0;for(var a=0;a=n&&(this.dMultiply(r),this.dAddOffset(u,0),o=0,u=0)}o>0&&(this.dMultiply(Math.pow(t,o)),this.dAddOffset(u,0)),s&&i.ZERO.subTo(this,this)}function ot(e,t,n){if("number"==typeof t)if(e<2)this.fromInt(1);else{this.fromNumber(e,n),this.testBit(e-1)||this.bitwiseTo(i.ONE.shiftLeft(e-1),dt,this),this.isEven()&&this.dAddOffset(1,0);while(!this.isProbablePrime(t))this.dAddOffset(2,0),this.bitLength()>e&&this.subTo(i.ONE.shiftLeft(e-1),this)}else{var r=new Array,s=e&7;r.length=(e>>3)+1,t.nextBytes(r),s>0?r[0]&=(1<0){n>n)!=(this.s&this.DM)>>n&&(t[i++]=r|this.s<=0){n<8?(r=(this.data[e]&(1<>(n+=this.DB-8)):(r=this.data[e]>>(n-=8)&255,n<=0&&(n+=this.DB,--e)),(r&128)!=0&&(r|=-256),i==0&&(this.s&128)!=(r&128)&&++i;if(i>0||r!=this.s)t[i++]=r}}return t}function at(e){return this.compareTo(e)==0}function ft(e){return this.compareTo(e)<0?this:e}function lt(e){return this.compareTo(e)>0?this:e}function ct(e,t,n){var r,i,s=Math.min(e.t,this.t);for(r=0;r>=16,t+=16),(e&255)==0&&(e>>=8,t+=8),(e&15)==0&&(e>>=4,t+=4),(e&3)==0&&(e>>=2,t+=2),(e&1)==0&&++t,t}function Tt(){for(var e=0;e=this.t?this.s!=0:(this.data[t]&1<>=this.DB;if(e.t>=this.DB;r+=this.s}else{r+=this.s;while(n>=this.DB;r+=e.s}t.s=r<0?-1:0,r>0?t.data[n++]=r:r<-1&&(t.data[n++]=this.DV+r),t.t=n,t.clamp()}function Dt(e){var t=s();return this.addTo(e,t),t}function Pt(e){var t=s();return this.subTo(e,t),t}function Ht(e){var t=s();return this.multiplyTo(e,t),t}function Bt(e){var t=s();return this.divRemTo(e,t,null),t}function jt(e){var t=s();return this.divRemTo(e,null,t),t}function Ft(e){var t=s(),n=s();return this.divRemTo(e,t,n),new Array(t,n)}function It(e){this.data[this.t]=this.am(0,e-1,this,0,0,this.t),++this.t,this.clamp()}function qt(e,t){if(e==0)return;while(this.t<=t)this.data[this.t++]=0;this.data[t]+=e;while(this.data[t]>=this.DV)this.data[t]-=this.DV,++t>=this.t&&(this.data[this.t++]=0),++this.data[t]}function Rt(){}function Ut(e){return e}function zt(e,t,n){e.multiplyTo(t,n)}function Wt(e,t){e.squareTo(t)}function Xt(e){return this.exp(e,new Rt)}function Vt(e,t,n){var r=Math.min(this.t+e.t,t);n.s=0,n.t=r;while(r>0)n.data[--r]=0;var i;for(i=n.t-this.t;r=0)n.data[r]=0;for(r=Math.max(t-this.t,0);r2*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=s();return e.copyTo(t),this.reduce(t),t}function Qt(e){return e}function Gt(e){e.drShiftTo(this.m.t-1,this.r2),e.t>this.m.t+1&&(e.t=this.m.t+1,e.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);while(e.compareTo(this.r2)<0)e.dAddOffset(1,this.m.t+1);e.subTo(this.r2,e);while(e.compareTo(this.m)>=0)e.subTo(this.m,e)}function Yt(e,t){e.squareTo(t),this.reduce(t)}function Zt(e,t,n){e.multiplyTo(t,n),this.reduce(n)}function en(e,t){var n=e.bitLength(),r,i=y(1),o;if(n<=0)return i;n<18?r=1:n<48?r=3:n<144?r=4:n<768?r=5:r=6,n<8?o=new B(t):t.isEven()?o=new Jt(t):o=new z(t);var u=new Array,a=3,f=r-1,l=(1<1){var c=s();o.sqrTo(u[1],c);while(a<=l)u[a]=s(),o.mulTo(c,u[a-2],u[a]),a+=2}var h=e.t-1,p,d=!0,v=s(),m;n=N(e.data[h])-1;while(h>=0){n>=f?p=e.data[h]>>n-f&l:(p=(e.data[h]&(1<0&&(p|=e.data[h-1]>>this.DB+n-f)),a=r;while((p&1)==0)p>>=1,--a;(n-=a)<0&&(n+=this.DB,--h);if(d)u[p].copyTo(i),d=!1;else{while(a>1)o.sqrTo(i,v),o.sqrTo(v,i),a-=2;a>0?o.sqrTo(i,v):(m=i,i=v,v=m),o.mulTo(v,u[p],i)}while(h>=0&&(e.data[h]&1<0&&(t.rShiftTo(s,t),n.rShiftTo(s,n));while(t.signum()>0)(i=t.getLowestSetBit())>0&&t.rShiftTo(i,t),(i=n.getLowestSetBit())>0&&n.rShiftTo(i,n),t.compareTo(n)>=0?(t.subTo(n,t),t.rShiftTo(1,t)):(n.subTo(t,n),n.rShiftTo(1,n));return s>0&&n.lShiftTo(s,n),n}function nn(e){if(e<=0)return 0;var t=this.DV%e,n=this.s<0?e-1:0;if(this.t>0)if(t==0)n=this.data[0]%e;else for(var r=this.t-1;r>=0;--r)n=(t*n+this.data[r])%e;return n}function rn(e){var t=e.isEven();if(this.isEven()&&t||e.signum()==0)return i.ZERO;var n=e.clone(),r=this.clone(),s=y(1),o=y(0),u=y(0),a=y(1);while(n.signum()!=0){while(n.isEven()){n.rShiftTo(1,n);if(t){if(!s.isEven()||!o.isEven())s.addTo(this,s),o.subTo(e,o);s.rShiftTo(1,s)}else o.isEven()||o.subTo(e,o);o.rShiftTo(1,o)}while(r.isEven()){r.rShiftTo(1,r);if(t){if(!u.isEven()||!a.isEven())u.addTo(this,u),a.subTo(e,a);u.rShiftTo(1,u)}else a.isEven()||a.subTo(e,a);a.rShiftTo(1,a)}n.compareTo(r)>=0?(n.subTo(r,n),t&&s.subTo(u,s),o.subTo(a,o)):(r.subTo(n,r),t&&u.subTo(s,u),a.subTo(o,a))}return r.compareTo(i.ONE)!=0?i.ZERO:a.compareTo(e)>=0?a.subtract(e):a.signum()<0?(a.addTo(e,a),a.signum()<0?a.add(e):a):a}function un(e){var t,n=this.abs();if(n.t==1&&n.data[0]<=sn[sn.length-1]){for(t=0;t=0);var a=o.modPow(r,this);if(a.compareTo(i.ONE)!=0&&a.compareTo(t)!=0){var f=1;while(f++>24&255,o>>16&255,o>>8&255,o&255);r.start(),r.update(t+u),i+=r.digest().getBytes()}return i.substring(0,n)}var t=e.pkcs1=e.pkcs1||{};t.encode_rsa_oaep=function(t,r,i){var s,o,u,a;typeof i=="string"?(s=i,o=arguments[3]||undefined,u=arguments[4]||undefined):i&&(s=i.label||undefined,o=i.seed||undefined,u=i.md||undefined,i.mgf1&&i.mgf1.md&&(a=i.mgf1.md)),u?u.start():u=e.md.sha1.create(),a||(a=u);var f=Math.ceil(t.n.bitLength()/8),l=f-2*u.digestLength-2;if(r.length>l)throw{message:"RSAES-OAEP input message length is too long.",length:r.length,maxLength:l};s||(s=""),u.update(s,"raw");var c=u.digest(),h="",p=l-r.length;for(var d=0;ds-11)throw{message:"Message is too long for PKCS#1 v1.5 padding.",length:t.length,max:s-11};i.putByte(0),i.putByte(r);var o=s-3-t.length,u;if(r===0||r===1){u=r===0?0:255;for(var a=0;a0){var f=0,l=e.random.getBytes(o);for(var a=0;a1){if(o.getByte()!==255){--o.read;break}++f}}else if(a===2){f=0;while(o.length()>1){if(o.getByte()===0){--o.read;break}++f}}var c=o.getByte();if(c!==0||f!==s-3-o.length())throw{message:"Encryption block is invalid."};return o.getBytes()}function p(n,i,s){function p(){u=Math.max(1,u),d(n.pBits,function(e,t){if(e)return s(e);n.p=t,d(n.qBits,v)})}function d(e,r){function d(){var r=e-1,i=new t(e,n.rng);return i.testBit(r)||i.bitwiseTo(t.ONE.shiftLeft(r),h,i),i.dAddOffset(31-i.mod(c).byteValue(),0),i}function m(s){if(v)return;--o;var u=s.data;if(u.found){for(var l=0;le&&(p=d());var c=p.toString(16);s.target.postMessage({e:n.eInt,hex:c,workLoad:a}),p.dAddOffset(f,0)}var i=[];for(var s=0;s="8"&&(n="00"+n),e.util.hexToBytes(n)}function v(e){return e<=100?27:e<=150?18:e<=200?15:e<=250?12:e<=300?9:e<=350?8:e<=400?7:e<=500?6:e<=600?5:e<=800?4:e<=1250?3:2}if(typeof t=="undefined")var t=e.jsbn.BigInteger;var n=e.asn1;e.pki=e.pki||{},e.pki.rsa=e.rsa=e.rsa||{};var r=e.pki,i=[6,4,2,4,2,4,6,2],s={name:"PrivateKeyInfo",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"PrivateKeyInfo.version",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"PrivateKeyInfo.privateKeyAlgorithm",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:n.Class.UNIVERSAL,type:n.Type.OID,constructed:!1,capture:"privateKeyOid"}]},{name:"PrivateKeyInfo",tagClass:n.Class.UNIVERSAL,type:n.Type.OCTETSTRING,constructed:!1,capture:"privateKey"}]},o={name:"RSAPrivateKey",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPrivateKey.version",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"RSAPrivateKey.modulus",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyModulus"},{name:"RSAPrivateKey.publicExponent",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyPublicExponent"},{name:"RSAPrivateKey.privateExponent",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyPrivateExponent"},{name:"RSAPrivateKey.prime1",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyPrime1"},{name:"RSAPrivateKey.prime2",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyPrime2"},{name:"RSAPrivateKey.exponent1",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyExponent1"},{name:"RSAPrivateKey.exponent2",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyExponent2"},{name:"RSAPrivateKey.coefficient",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"privateKeyCoefficient"}]},u={name:"RSAPublicKey",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPublicKey.modulus",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"publicKeyModulus"},{name:"RSAPublicKey.exponent",tagClass:n.Class.UNIVERSAL,type:n.Type.INTEGER,constructed:!1,capture:"publicKeyExponent"}]},a=e.pki.rsa.publicKeyValidator={name:"SubjectPublicKeyInfo",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,captureAsn1:"subjectPublicKeyInfo",value:[{name:"SubjectPublicKeyInfo.AlgorithmIdentifier",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:n.Class.UNIVERSAL,type:n.Type.OID,constructed:!1,capture:"publicKeyOid"}]},{name:"SubjectPublicKeyInfo.subjectPublicKey",tagClass:n.Class.UNIVERSAL,type:n.Type.BITSTRING,constructed:!1,value:[{name:"SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey",tagClass:n.Class.UNIVERSAL,type:n.Type.SEQUENCE,constructed:!0,optional:!0,captureAsn1:"rsaPublicKey"}]}]},f=function(e){var t;if(e.algorithm in r.oids){t=r.oids[e.algorithm];var i=n.oidToDer(t).getBytes(),s=n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[]),o=n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[]);o.value.push(n.create(n.Class.UNIVERSAL,n.Type.OID,!1,i)),o.value.push(n.create(n.Class.UNIVERSAL,n.Type.NULL,!1,""));var u=n.create(n.Class.UNIVERSAL,n.Type.OCTETSTRING,!1,e.digest().getBytes());return s.value.push(o),s.value.push(u),n.toDer(s).getBytes()}throw{message:"Unknown message digest algorithm.",algorithm:e.algorithm}},l=function(n,r,i){if(i)return n.modPow(r.e,r.n);if(!r.p||!r.q)return n.modPow(r.d,r.n);r.dP||(r.dP=r.d.mod(r.p.subtract(t.ONE))),r.dQ||(r.dQ=r.d.mod(r.q.subtract(t.ONE))),r.qInv||(r.qInv=r.q.modInverse(r.p));var s;do s=(new t(e.util.bytesToHex(e.random.getBytes(r.n.bitLength()/8)),16)).mod(r.n);while(s.equals(t.ZERO));n=n.multiply(s.modPow(r.e,r.n)).mod(r.n);var o=n.mod(r.p).modPow(r.dP,r.p),u=n.mod(r.q).modPow(r.dQ,r.q);while(o.compareTo(u)<0)o=o.add(r.p);var a=o.subtract(u).multiply(r.qInv).mod(r.p).multiply(r.q).add(u);return a=a.multiply(s.modInverse(r.n)).mod(r.n),a};r.rsa.encrypt=function(n,r,i){var s=i,o,u=Math.ceil(r.n.bitLength()/8);i!==!1&&i!==!0?(s=i===2,o=c(n,r,i)):(o=e.util.createBuffer(),o.putBytes(n));var a=new t(o.toHex(),16),f=l(a,r,s),h=f.toString(16),p=e.util.createBuffer(),d=u-Math.ceil(h.length/2);while(d>0)p.putByte(0),--d;return p.putBytes(e.util.hexToBytes(h)),p.getBytes()},r.rsa.decrypt=function(n,r,i,s){var o=Math.ceil(r.n.bitLength()/8);if(n.length!==o)throw{message:"Encrypted message length is invalid.",length:n.length,expected:o};var u=new t(e.util.createBuffer(n).toHex(),16);if(u.compareTo(r.n)>=0)throw{message:"Encrypted message is invalid."};var a=l(u,r,i),f=a.toString(16),c=e.util.createBuffer(),p=o-Math.ceil(f.length/2);while(p>0)c.putByte(0),--p;return c.putBytes(e.util.hexToBytes(f)),s!==!1?h(c.getBytes(),r,i):c.getBytes()},r.rsa.createKeyPairGenerationState=function(n,r,i){typeof n=="string"&&(n=parseInt(n,10)),n=n||2048,i=i||{},i.prng=i.prng||e.random;var s={nextBytes:function(e){var t=i.prng.getBytesSync(e.length);for(var n=0;n>1,pBits:n-(n>>1),pqState:0,num:null,keys:null};return o.e.fromInt(o.eInt),o},r.rsa.stepKeyPairGenerationState=function(e,n){var s=new t(null);s.fromInt(30);var o=0,u=function(e,t){return e|t},a=+(new Date),f,l=0;while(e.keys===null&&(n<=0||lc?e.pqState=0:e.num.isProbablePrime(v(e.num.bitLength()))?++e.pqState:e.num.dAddOffset(i[o++%8],0):e.pqState===2?e.pqState=e.num.subtract(t.ONE).gcd(e.e).compareTo(t.ONE)===0?3:0:e.pqState===3&&(e.pqState=0,e.p===null?e.p=e.num:e.q=e.num,e.p!==null&&e.q!==null&&++e.state,e.num=null)}else if(e.state===1)e.p.compareTo(e.q)<0&&(e.num=e.p,e.p=e.q,e.q=e.num),++e.state;else if(e.state===2)e.p1=e.p.subtract(t.ONE),e.q1=e.q.subtract(t.ONE),e.phi=e.p1.multiply(e.q1),++e.state;else if(e.state===3)e.phi.gcd(e.e).compareTo(t.ONE)===0?++e.state:(e.p=null,e.q=null,e.state=0);else if(e.state===4)e.n=e.p.multiply(e.q),e.n.bitLength()===e.bits?++e.state:(e.q=null,e.state=0);else if(e.state===5){var p=e.e.modInverse(e.phi);e.keys={privateKey:r.rsa.setPrivateKey(e.n,e.e,p,e.p,e.q,p.mod(e.p1),p.mod(e.q1),e.q.modInverse(e.p)),publicKey:r.rsa.setPublicKey(e.n,e.e)}}f=+(new Date),l+=f-a,a=f}return e.keys!==null},r.rsa.generateKeyPair=function(e,t,n,i){arguments.length===1?typeof e=="object"?(n=e,e=undefined):typeof e=="function"&&(i=e,e=undefined):arguments.length===2?typeof e=="number"?typeof t=="function"?(i=t,t=undefined):typeof t!="number"&&(n=t,t=undefined):(n=e,i=t,e=undefined,t=undefined):arguments.length===3&&(typeof t=="number"?typeof n=="function"&&(i=n,n=undefined):(i=n,n=t,t=undefined)),n=n||{},e===undefined&&(e=n.bits||2048),t===undefined&&(t=n.e||65537);var s=r.rsa.createKeyPairGenerationState(e,t,n);if(!i)return r.rsa.stepKeyPairGenerationState(s,0),s.keys;p(s,n,i)},r.setRsaPublicKey=r.rsa.setPublicKey=function(t,i){var s={n:t,e:i};return s.encrypt=function(t,n,i){typeof n=="string"?n=n.toUpperCase():n===undefined&&(n="RSAES-PKCS1-V1_5");if(n==="RSAES-PKCS1-V1_5")n={encode:function(e,t,n){return c(e,t,2).getBytes()}};else if(n==="RSA-OAEP"||n==="RSAES-OAEP")n={encode:function(t,n){return e.pkcs1.encode_rsa_oaep(n,t,i)}};else{if(["RAW","NONE","NULL",null].indexOf(n)===-1)throw{message:'Unsupported encryption scheme: "'+n+'".'};n={encode:function(e){return e}}}var o=n.encode(t,s,!0);return r.rsa.encrypt(o,s,!0)},s.verify=function(e,t,i){typeof i=="string"?i=i.toUpperCase():i===undefined&&(i="RSASSA-PKCS1-V1_5");if(i==="RSASSA-PKCS1-V1_5")i={verify:function(e,t){t=h(t,s,!0);var r=n.fromDer(t);return e===r.value[1].value}};else if(i==="NONE"||i==="NULL"||i===null)i={verify:function(e,t){return t=h(t,s,!0),e===t}};var o=r.rsa.decrypt(t,s,!0,!1);return i.verify(e,o,s.n.bitLength())},s},r.setRsaPrivateKey=r.rsa.setPrivateKey=function(t,n,i,s,o,u,a,l){var c={n:t,e:n,d:i,p:s,q:o,dP:u,dQ:a,qInv:l};return c.decrypt=function(t,n,i){typeof n=="string"?n=n.toUpperCase():n===undefined&&(n="RSAES-PKCS1-V1_5");var s=r.rsa.decrypt(t,c,!1,!1);if(n==="RSAES-PKCS1-V1_5")n={decode:h};else if(n==="RSA-OAEP"||n==="RSAES-OAEP")n={decode:function(t,n){return e.pkcs1.decode_rsa_oaep(n,t,i)}};else{if(["RAW","NONE","NULL",null].indexOf(n)===-1)throw{message:'Unsupported encryption scheme: "'+n+'".'};n={decode:function(e){return e}}}return n.decode(s,c,!1)},c.sign=function(e,t){var n=!1;typeof t=="string"&&(t=t.toUpperCase());if(t===undefined||t==="RSASSA-PKCS1-V1_5")t={encode:f},n=1;else if(t==="NONE"||t==="NULL"||t===null)t={encode:function(){return e}},n=1;var i=t.encode(e,c.n.bitLength());return r.rsa.encrypt(i,c,n)},c},r.wrapRsaPrivateKey=function(e){return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,n.integerToDer(0).getBytes()),n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.OID,!1,n.oidToDer(r.oids.rsaEncryption).getBytes()),n.create(n.Class.UNIVERSAL,n.Type.NULL,!1,"")]),n.create(n.Class.UNIVERSAL,n.Type.OCTETSTRING,!1,n.toDer(e).getBytes())])},r.privateKeyFromAsn1=function(i){var u={},a=[];n.validate(i,s,u,a)&&(i=n.fromDer(e.util.createBuffer(u.privateKey))),u={},a=[];if(!n.validate(i,o,u,a))throw{message:"Cannot read private key. ASN.1 object does not contain an RSAPrivateKey.",errors:a};var f,l,c,h,p,d,v,m;return f=e.util.createBuffer(u.privateKeyModulus).toHex(),l=e.util.createBuffer(u.privateKeyPublicExponent).toHex(),c=e.util.createBuffer(u.privateKeyPrivateExponent).toHex(),h=e.util.createBuffer(u.privateKeyPrime1).toHex(),p=e.util.createBuffer(u.privateKeyPrime2).toHex(),d=e.util.createBuffer(u.privateKeyExponent1).toHex(),v=e.util.createBuffer(u.privateKeyExponent2).toHex(),m=e.util.createBuffer(u.privateKeyCoefficient).toHex(),r.setRsaPrivateKey(new t(f,16),new t(l,16),new t(c,16),new t(h,16),new t(p,16),new t(d,16),new t(v,16),new t(m,16))},r.privateKeyToAsn1=r.privateKeyToRSAPrivateKey=function(e){return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,n.integerToDer(0).getBytes()),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.n)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.e)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.d)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.p)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.q)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.dP)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.dQ)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.qInv))])},r.publicKeyFromAsn1=function(i){var s={},o=[];if(n.validate(i,a,s,o)){var f=n.derToOid(s.publicKeyOid);if(f!==r.oids.rsaEncryption)throw{message:"Cannot read public key. Unknown OID.",oid:f};i=s.rsaPublicKey}o=[];if(!n.validate(i,u,s,o))throw{message:"Cannot read public key. ASN.1 object does not contain an RSAPublicKey.",errors:o};var l=e.util.createBuffer(s.publicKeyModulus).toHex(),c=e.util.createBuffer(s.publicKeyExponent).toHex();return r.setRsaPublicKey(new t(l,16),new t(c,16))},r.publicKeyToAsn1=r.publicKeyToSubjectPublicKeyInfo=function(e){return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.OID,!1,n.oidToDer(r.oids.rsaEncryption).getBytes()),n.create(n.Class.UNIVERSAL,n.Type.NULL,!1,"")]),n.create(n.Class.UNIVERSAL,n.Type.BITSTRING,!1,[r.publicKeyToRSAPublicKey(e)])])},r.publicKeyToRSAPublicKey=function(e){return n.create(n.Class.UNIVERSAL,n.Type.SEQUENCE,!0,[n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.n)),n.create(n.Class.UNIVERSAL,n.Type.INTEGER,!1,d(e.e))])}}var r="rsa";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=0;a--)A>>=8,A+=N.at(a)+L.at(a),L.setAt(a,A&255);k.putBuffer(L)}w=k,c.putBuffer(x)}return c.truncate(c.length()-s),c},r.pbe.getCipher=function(e,t,n){switch(e){case r.oids.pkcs5PBES2:return r.pbe.getCipherForPBES2(e,t,n);case r.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:case r.oids["pbewithSHAAnd40BitRC2-CBC"]:return r.pbe.getCipherForPKCS12PBE(e,t,n);default:throw{message:"Cannot read encrypted PBE data block. Unsupported OID.",oid:e,supportedOids:["pkcs5PBES2","pbeWithSHAAnd3-KeyTripleDES-CBC","pbewithSHAAnd40BitRC2-CBC"]}}},r.pbe.getCipherForPBES2=function(t,i,s){var u={},a=[];if(!n.validate(i,o,u,a))throw{message:"Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.",errors:a};t=n.derToOid(u.kdfOid);if(t!==r.oids.pkcs5PBKDF2)throw{message:"Cannot read encrypted private key. Unsupported key derivation function OID.",oid:t,supportedOids:["pkcs5PBKDF2"]};t=n.derToOid(u.encOid);if(t!==r.oids["aes128-CBC"]&&t!==r.oids["aes192-CBC"]&&t!==r.oids["aes256-CBC"]&&t!==r.oids["des-EDE3-CBC"]&&t!==r.oids.desCBC)throw{message:"Cannot read encrypted private key. Unsupported encryption scheme OID.",oid:t,supportedOids:["aes128-CBC","aes192-CBC","aes256-CBC","des-EDE3-CBC","desCBC"]};var f=u.kdfSalt,l=e.util.createBuffer(u.kdfIterationCount);l=l.getInt(l.length()<<3);var c,h;switch(r.oids[t]){case"aes128-CBC":c=16,h=e.aes.createDecryptionCipher;break;case"aes192-CBC":c=24,h=e.aes.createDecryptionCipher;break;case"aes256-CBC":c=32,h=e.aes.createDecryptionCipher;break;case"des-EDE3-CBC":c=24,h=e.des.createDecryptionCipher;break;case"desCBC":c=8,h=e.des.createDecryptionCipher}var p=e.pkcs5.pbkdf2(s,f,l,c),d=u.encIv,v=h(p);return v.start(d),v},r.pbe.getCipherForPKCS12PBE=function(t,i,s){var o={},a=[];if(!n.validate(i,u,o,a))throw{message:"Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.",errors:a};var f=e.util.createBuffer(o.salt),l=e.util.createBuffer(o.iterations);l=l.getInt(l.length()<<3);var c,h,p;switch(t){case r.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:c=24,h=8,p=e.des.startDecrypting;break;case r.oids["pbewithSHAAnd40BitRC2-CBC"]:c=5,h=8,p=function(t,n){var r=e.rc2.createDecryptionCipher(t,40);return r.start(n,null),r};break;default:throw{message:"Cannot read PKCS #12 PBE data block. Unsupported OID.",oid:t}}var d=r.pbe.generatePkcs12Key(s,f,1,l,c),v=r.pbe.generatePkcs12Key(s,f,2,l,h);return p(d,v)}}var r="pbe";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o>8*l-f&255;if((h.charCodeAt(0)&d)!==0)throw{message:"Bits beyond keysize not zero as expected."};var v=n.generate(p,c),m="";for(a=0;a>8*f-a&255;return y=String.fromCharCode(y.charCodeAt(0)&~b)+y.substr(1),y+p+String.fromCharCode(188)},s}}var r="pss";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o1&&(c=l.value.charCodeAt(1),h=l.value.length>2?l.value.charCodeAt(2):0),s.digitalSignature=(c&128)===128,s.nonRepudiation=(c&64)===64,s.keyEncipherment=(c&32)===32,s.dataEncipherment=(c&16)===16,s.keyAgreement=(c&8)===8,s.keyCertSign=(c&4)===4,s.cRLSign=(c&2)===2,s.encipherOnly=(c&1)===1,s.decipherOnly=(h&128)===128}else if(s.name==="basicConstraints"){var l=t.fromDer(s.value);l.value.length>0&&l.value[0].type===t.Type.BOOLEAN?s.cA=l.value[0].value.charCodeAt(0)!==0:s.cA=!1;var p=null;l.value.length>0&&l.value[0].type===t.Type.INTEGER?p=l.value[0].value:l.value.length>1&&(p=l.value[1].value),p!==null&&(s.pathLenConstraint=t.derToInteger(p))}else if(s.name==="extKeyUsage"){var l=t.fromDer(s.value);for(var d=0;d1&&(c=l.value.charCodeAt(1)),s.client=(c&128)===128,s.server=(c&64)===64,s.email=(c&32)===32,s.objsign=(c&16)===16,s.reserved=(c&8)===8,s.sslCA=(c&4)===4,s.emailCA=(c&2)===2,s.objCA=(c&1)===1}else if(s.name==="subjectAltName"||s.name==="issuerAltName"){s.altNames=[];var m,l=t.fromDer(s.value);for(var g=0;g2)throw{message:"Cannot read notBefore/notAfter validity times; more than two times were provided in the certificate."};if(b.length<2)throw{message:"Cannot read notBefore/notAfter validity times; they were not provided as either UTCTime or GeneralizedTime."};v.validity.notBefore=b[0],v.validity.notAfter=b[1],v.tbsCertificate=u.tbsCertificate;if(s){v.md=null;if(v.signatureOid in r){var d=r[v.signatureOid];switch(d){case"sha1WithRSAEncryption":v.md=e.md.sha1.create();break;case"md5WithRSAEncryption":v.md=e.md.md5.create();break;case"sha256WithRSAEncryption":v.md=e.md.sha256.create();break;case"RSASSA-PSS":v.md=e.md.sha256.create()}}if(v.md===null)throw{message:"Could not compute certificate digest. Unknown signature OID.",signatureOid:v.signatureOid};var w=t.toDer(v.tbsCertificate);v.md.update(w.getBytes())}var E=e.md.sha1.create();v.issuer.getField=function(e){return l(v.issuer,e)},v.issuer.addField=function(e){m([e]),v.issuer.attributes.push(e)},v.issuer.attributes=n.RDNAttributesAsArray(u.certIssuer,E),u.certIssuerUniqueId&&(v.issuer.uniqueId=u.certIssuerUniqueId),v.issuer.hash=E.digest().toHex();var S=e.md.sha1.create();return v.subject.getField=function(e){return l(v.subject,e)},v.subject.addField=function(e){m([e]),v.subject.attributes.push(e)},v.subject.attributes=n.RDNAttributesAsArray(u.certSubject,S),u.certSubjectUniqueId&&(v.subject.uniqueId=u.certSubjectUniqueId),v.subject.hash=S.digest().toHex(),u.certExtensions?v.extensions=c(u.certExtensions):v.extensions=[],v.publicKey=n.publicKeyFromAsn1(u.subjectPublicKeyInfo),v},n.certificationRequestFromAsn1=function(i,s){var o={},u=[];if(!t.validate(i,f,o,u))throw{message:"Cannot read PKCS#10 certificate request. ASN.1 object is not a PKCS#10 CertificationRequest.",errors:u};if(typeof o.csrSignature!="string"){var a="\0";for(var c=0;c0&&i.value.push(d(r.extensions)),i},n.getCertificationRequestInfo=function(e){var r=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,t.integerToDer(e.version).getBytes()),p(e.subject),n.publicKeyToAsn1(e.publicKey),y(e)]);return r},n.distinguishedNameToAsn1=function(e){return p(e)},n.certificateToAsn1=function(e){var r=e.tbsCertificate||n.getTBSCertificate(e);return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[r,t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(e.signatureOid).getBytes()),g(e.signatureOid,e.signatureParameters)]),t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,String.fromCharCode(0)+e.signature)])},n.certificationRequestToAsn1=function(e){var r=e.certificationRequestInfo||n.getCertificationRequestInfo(e);return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[r,t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(e.signatureOid).getBytes()),g(e.signatureOid,e.signatureParameters)]),t.create(t.Class.UNIVERSAL,t.Type.BITSTRING,!1,String.fromCharCode(0)+e.signature)])},n.createCaStore=function(t){var r={certs:{}};r.getIssuer=function(t){var i=null;if(!t.issuer.hash){var s=e.md.sha1.create();t.issuer.attributes=n.RDNAttributesAsArray(p(t.issuer),s),t.issuer.hash=s.digest().toHex()}if(t.issuer.hash in r.certs){i=r.certs[t.issuer.hash];if(e.util.isArray(i))throw{message:"Resolving multiple issuer matches not implemented yet."}}return i},r.addCertificate=function(t){typeof t=="string"&&(t=e.pki.certificateFromPem(t));if(!t.subject.hash){var i=e.md.sha1.create();t.subject.attributes=n.RDNAttributesAsArray(p(t.subject),i),t.subject.hash=i.digest().toHex()}if(t.subject.hash in r.certs){var s=r.certs[t.subject.hash];e.util.isArray(s)||(s=[s]),s.push(t)}else r.certs[t.subject.hash]=t};if(t)for(var i=0;ic.validity.notAfter)a={message:"Certificate is not valid yet or has expired.",error:n.certificateError.certificate_expired,notBefore:c.validity.notBefore,notAfter:c.validity.notAfter,now:o};else{var h=!1;if(r.length>0){l=r[0];try{h=l.verify(c)}catch(p){}}else{var d=t.getIssuer(c);if(d===null)a={message:"Certificate is not trusted.",error:n.certificateError.unknown_ca};else{e.util.isArray(d)||(d=[d]);while(!h&&d.length>0){l=d.shift();try{h=l.verify(c)}catch(p){}}}}a===null&&!h&&(a={message:"Certificate signature is invalid.",error:n.certificateError.bad_certificate})}a===null&&!c.isIssuer(l)&&(a={message:"Certificate issuer is invalid.",error:n.certificateError.bad_certificate});if(a===null){var v={keyUsage:!0,basicConstraints:!0};for(var m=0;a===null&&mE&&(a={message:"Certificate basicConstraints pathLenConstraint violated.",error:n.certificateError.bad_certificate})}}var S=a===null?!0:a.error,x=i?i(S,f,s):S;if(x!==!0){S===!0&&(a={message:"The application rejected the certificate.",error:n.certificateError.bad_certificate});if(x||x===0)typeof x=="object"&&!e.util.isArray(x)?(x.message&&(a.message=x.message),x.error&&(a.error=x.error)):typeof x=="string"&&(a.error=x);throw a}a=null,u=!1,++f}while(r.length>0);return!0}}var r="x509";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=0&&i.push(u)}return i}function l(e,r,s,o){r=t.fromDer(r,s);if(r.tagClass!==t.Class.UNIVERSAL||r.type!==t.Type.SEQUENCE||r.constructed!==!0)throw{message:"PKCS#12 AuthenticatedSafe expected to be a SEQUENCE OF ContentInfo"};for(var u=0;u0&&(f=t.create(t.Class.UNIVERSAL,t.Type.SET,!0,h));var p=[],d=[];s!==null&&(e.util.isArray(s)?d=s:d=[s]);var v=[];for(var m=0;m0){var w=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,v),E=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.data).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(w).getBytes())])]);p.push(E)}var S=null;if(i!==null){var x=n.wrapRsaPrivateKey(n.privateKeyToAsn1(i));o===null?S=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.keyBag).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[x]),f]):S=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.pkcs8ShroudedKeyBag).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[n.encryptPrivateKeyInfo(x,o,u)]),f]);var T=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[S]),N=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.data).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(T).getBytes())])]);p.push(N)}var C=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,p),k;if(u.useMac){var c=e.md.sha1.create(),L=new e.util.ByteBuffer(e.random.getBytes(u.saltSize)),A=u.count,i=r.generateKey(o||"",L,3,A,20),O=e.hmac.create();O.start(c,i),O.update(t.toDer(C).getBytes());var M=O.getMac();k=t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.sha1).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.NULL,!1,"")]),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,M.getBytes())]),t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,L.getBytes()),t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,t.integerToDer(A).getBytes())])}return t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.INTEGER,!1,t.integerToDer(3).getBytes()),t.create(t.Class.UNIVERSAL,t.Type.SEQUENCE,!0,[t.create(t.Class.UNIVERSAL,t.Type.OID,!1,t.oidToDer(n.oids.data).getBytes()),t.create(t.Class.CONTEXT_SPECIFIC,0,!0,[t.create(t.Class.UNIVERSAL,t.Type.OCTETSTRING,!1,t.toDer(C).getBytes())])]),k])},r.generateKey=e.pbe.generatePkcs12Key}var r="pkcs12";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o>1,u=o+(t.length&1),a=t.substr(0,u),f=t.substr(o,u),l=e.util.createBuffer(),c=e.hmac.create();r=n+r;var h=Math.ceil(i/16),p=Math.ceil(i/20);c.start("MD5",a);var d=e.util.createBuffer();l.putBytes(r);for(var v=0;v0&&(a.queue(e,a.createAlert(e,{level:a.Alert.Level.warning,description:a.Alert.Description.no_renegotiation})),a.flush(e)),e.process()},a.parseHelloMessage=function(t,n,r){var i=null,s=t.entity===a.ConnectionEnd.client;if(r<38)t.error(t,{message:s?"Invalid ServerHello message. Message too short.":"Invalid ClientHello message. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});else{var u=n.fragment,f=u.length();i={version:{major:u.getByte(),minor:u.getByte()},random:e.util.createBuffer(u.getBytes(32)),session_id:o(u,1),extensions:[]},s?(i.cipher_suite=u.getBytes(2),i.compression_method=u.getByte()):(i.cipher_suites=o(u,2),i.compression_methods=o(u,1)),f=r-(f-u.length());if(f>0){var l=o(u,2);while(l.length()>0)i.extensions.push({type:[l.getByte(),l.getByte()],data:o(l,2)});if(!s)for(var c=0;c0){var d=p.getByte();if(d!==0)break;t.session.extensions.server_name.serverNameList.push(o(p,2).getBytes())}}}}if(t.session.version)if(i.version.major!==t.session.version.major||i.version.minor!==t.session.version.minor)return t.error(t,{message:"TLS version change is disallowed during renegotiation.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.protocol_version}});if(s)t.session.cipherSuite=a.getCipherSuite(i.cipher_suite);else{var v=e.util.createBuffer(i.cipher_suites.bytes());while(v.length()>0){t.session.cipherSuite=a.getCipherSuite(v.getBytes(2));if(t.session.cipherSuite!==null)break}}if(t.session.cipherSuite===null)return t.error(t,{message:"No cipher suites in common.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.handshake_failure},cipherSuite:e.util.bytesToHex(i.cipher_suite)});s?t.session.compressionMethod=i.compression_method:t.session.compressionMethod=a.CompressionMethod.none}return i},a.createSecurityParameters=function(e,t){var n=e.entity===a.ConnectionEnd.client,r=t.random.bytes(),i=n?e.session.sp.client_random:r,s=n?r:a.createRandom().getBytes();e.session.sp={entity:e.entity,prf_algorithm:a.PRFAlgorithm.tls_prf_sha256,bulk_cipher_algorithm:null,cipher_type:null,enc_key_length:null,block_length:null,fixed_iv_length:null,record_iv_length:null,mac_algorithm:null,mac_length:null,mac_key_length:null,compression_algorithm:e.session.compressionMethod,pre_master_secret:null,master_secret:null,client_random:i,server_random:s}},a.handleServerHello=function(e,t,n){var r=a.parseHelloMessage(e,t,n);if(e.fail)return;if(!(r.version.minor<=e.version.minor))return e.error(e,{message:"Incompatible TLS version.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.protocol_version}});e.version.minor=r.version.minor,e.session.version=e.version;var i=r.session_id.bytes();i.length>0&&i===e.session.id?(e.expect=d,e.session.resuming=!0,e.session.sp.server_random=r.random.bytes()):(e.expect=l,e.session.resuming=!1,a.createSecurityParameters(e,r)),e.session.id=i,e.process()},a.handleClientHello=function(t,n,r){var i=a.parseHelloMessage(t,n,r);if(t.fail)return;var s=i.session_id.bytes(),o=null;if(t.sessionCache){o=t.sessionCache.getSession(s);if(o===null)s="";else if(o.version.major!==i.version.major||o.version.minor>i.version.minor)o=null,s=""}s.length===0&&(s=e.random.getBytes(32)),t.session.id=s,t.session.clientHelloVersion=i.version,t.session.sp={};if(o)t.version=t.session.version=o.version,t.session.sp=o.sp;else{var u;for(var f=1;f0)u=o(s.certificate_list,3),f=e.asn1.fromDer(u),u=e.pki.certificateFromAsn1(f,!0),l.push(u)}catch(h){return t.error(t,{message:"Could not parse certificate list.",cause:h,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.bad_certificate}})}var p=t.entity===a.ConnectionEnd.client;!p&&t.verifyClient!==!0||l.length!==0?l.length===0?t.expect=p?c:w:(p?t.session.serverCertificate=l[0]:t.session.clientCertificate=l[0],a.verifyCertificateChain(t,l)&&(t.expect=p?c:w)):t.error(t,{message:p?"No server certificate provided.":"No client certificate provided.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}}),t.process()},a.handleServerKeyExchange=function(e,t,n){if(n>0)return e.error(e,{message:"Invalid key parameters. Only RSA is supported.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.unsupported_certificate}});e.expect=h,e.process()},a.handleClientKeyExchange=function(t,n,r){if(r<48)return t.error(t,{message:"Invalid key parameters. Only RSA is supported.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.unsupported_certificate}});var i=n.fragment,s={enc_pre_master_secret:o(i,2).getBytes()},u=null;if(t.getPrivateKey)try{u=t.getPrivateKey(t,t.session.serverCertificate),u=e.pki.privateKeyFromPem(u)}catch(f){t.error(t,{message:"Could not get private key.",cause:f,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}})}if(u===null)return t.error(t,{message:"No private key set.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}});try{var l=t.session.sp;l.pre_master_secret=u.decrypt(s.enc_pre_master_secret);var c=t.session.clientHelloVersion;if(c.major!==l.pre_master_secret.charCodeAt(0)||c.minor!==l.pre_master_secret.charCodeAt(1))throw{message:"TLS version rollback attack detected."}}catch(f){l.pre_master_secret=e.random.getBytes(48)}t.expect=S,t.session.clientCertificate!==null&&(t.expect=E),t.process()},a.handleCertificateRequest=function(e,t,n){if(n<3)return e.error(e,{message:"Invalid CertificateRequest. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});var r=t.fragment,i={certificate_types:o(r,1),certificate_authorities:o(r,2)};e.session.certificateRequest=i,e.expect=p,e.process()},a.handleCertificateVerify=function(t,n,r){if(r<2)return t.error(t,{message:"Invalid CertificateVerify. Message too short.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});var i=n.fragment;i.read-=4;var s=i.bytes();i.read+=4;var u={signature:o(i,2).getBytes()},f=e.util.createBuffer();f.putBuffer(t.session.md5.digest()),f.putBuffer(t.session.sha1.digest()),f=f.getBytes();try{var l=t.session.clientCertificate;if(!l.publicKey.verify(f,u.signature,"NONE"))throw{message:"CertificateVerify signature does not match."};t.session.md5.update(s),t.session.sha1.update(s)}catch(c){return t.error(t,{message:"Bad signature in CertificateVerify.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.handshake_failure}})}t.expect=S,t.process()},a.handleServerHelloDone=function(t,n,r){if(r>0)return t.error(t,{message:"Invalid ServerHelloDone message. Invalid length.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.record_overflow}});if(t.serverCertificate===null){var i={message:"No server certificate provided. Not enough security.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.insufficient_security}},s=0,o=t.verify(t,i.alert.description,s,[]);if(o!==!0){if(o||o===0)typeof o=="object"&&!e.util.isArray(o)?(o.message&&(i.message=o.message),o.alert&&(i.alert.description=o.alert)):typeof o=="number"&&(i.alert.description=o);return t.error(t,i)}}t.session.certificateRequest!==null&&(n=a.createRecord(t,{type:a.ContentType.handshake,data:a.createCertificate(t)}),a.queue(t,n)),n=a.createRecord(t,{type:a.ContentType.handshake,data:a.createClientKeyExchange(t)}),a.queue(t,n),t.expect=g;var u=function(e,t){e.session.certificateRequest!==null&&e.session.clientCertificate!==null&&a.queue(e,a.createRecord(e,{type:a.ContentType.handshake,data:a.createCertificateVerify(e,t)})),a.queue(e,a.createRecord(e,{type:a.ContentType.change_cipher_spec,data:a.createChangeCipherSpec()})),e.state.pending=a.createConnectionState(e),e.state.current.write=e.state.pending.write,a.queue(e,a.createRecord(e,{type:a.ContentType.handshake,data:a.createFinished(e)})),e.expect=d,a.flush(e),e.process()};if(t.session.certificateRequest===null||t.session.clientCertificate===null)return u(t,null);a.getClientSignature(t,u)},a.handleChangeCipherSpec=function(e,t){if(t.fragment.getByte()!==1)return e.error(e,{message:"Invalid ChangeCipherSpec message received.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.illegal_parameter}});var n=e.entity===a.ConnectionEnd.client;if(e.session.resuming&&n||!e.session.resuming&&!n)e.state.pending=a.createConnectionState(e);e.state.current.read=e.state.pending.read;if(!e.session.resuming&&n||e.session.resuming&&!n)e.state.pending=null;e.expect=n?v:x,e.process()},a.handleFinished=function(n,r,i){var s=r.fragment;s.read-=4;var o=s.bytes();s.read+=4;var u=r.fragment.getBytes();s=e.util.createBuffer(),s.putBuffer(n.session.md5.digest()),s.putBuffer(n.session.sha1.digest());var f=n.entity===a.ConnectionEnd.client,l=f?"server finished":"client finished",c=n.session.sp,h=12,p=t;s=p(c.master_secret,l,s.getBytes(),h);if(s.getBytes()!==u)return n.error(n,{message:"Invalid verify_data in Finished message.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.decrypt_error}});n.session.md5.update(o),n.session.sha1.update(o);if(n.session.resuming&&f||!n.session.resuming&&!f)a.queue(n,a.createRecord(n,{type:a.ContentType.change_cipher_spec,data:a.createChangeCipherSpec()})),n.state.current.write=n.state.pending.write,n.state.pending=null,a.queue(n,a.createRecord(n,{type:a.ContentType.handshake,data:a.createFinished(n)}));n.expect=f?m:T,n.handshaking=!1,++n.handshakes,n.peerCertificate=f?n.session.serverCertificate:n.session.clientCertificate,a.flush(n),n.isConnected=!0,n.connected(n),n.process()},a.handleAlert=function(e,t){var n=t.fragment,r={level:n.getByte(),description:n.getByte()},i;switch(r.description){case a.Alert.Description.close_notify:i="Connection closed.";break;case a.Alert.Description.unexpected_message:i="Unexpected message.";break;case a.Alert.Description.bad_record_mac:i="Bad record MAC.";break;case a.Alert.Description.decryption_failed:i="Decryption failed.";break;case a.Alert.Description.record_overflow:i="Record overflow.";break;case a.Alert.Description.decompression_failure:i="Decompression failed.";break;case a.Alert.Description.handshake_failure:i="Handshake failure.";break;case a.Alert.Description.bad_certificate:i="Bad certificate.";break;case a.Alert.Description.unsupported_certificate:i="Unsupported certificate.";break;case a.Alert.Description.certificate_revoked:i="Certificate revoked.";break;case a.Alert.Description.certificate_expired:i="Certificate expired.";break;case a.Alert.Description.certificate_unknown:i="Certificate unknown.";break;case a.Alert.Description.illegal_parameter:i="Illegal parameter.";break;case a.Alert.Description.unknown_ca:i="Unknown certificate authority.";break;case a.Alert.Description.access_denied:i="Access denied.";break;case a.Alert.Description.decode_error:i="Decode error.";break;case a.Alert.Description.decrypt_error:i="Decrypt error.";break;case a.Alert.Description.export_restriction:i="Export restriction.";break;case a.Alert.Description.protocol_version:i="Unsupported protocol version.";break;case a.Alert.Description.insufficient_security:i="Insufficient security.";break;case a.Alert.Description.internal_error:i="Internal error.";break;case a.Alert.Description.user_canceled:i="User canceled.";break;case a.Alert.Description.no_renegotiation:i="Renegotiation not supported.";break;default:i="Unknown error."}if(r.description===a.Alert.Description.close_notify)return e.close();e.error(e,{message:i,send:!1,origin:e.entity===a.ConnectionEnd.client?"server":"client",alert:r}),e.process()},a.handleHandshake=function(t,n){var r=n.fragment,i=r.getByte(),s=r.getInt24();if(s>r.length())return t.fragmented=n,n.fragment=e.util.createBuffer(),r.read-=4,t.process();t.fragmented=null,r.read-=4;var o=r.bytes(s+4);r.read+=4,i in q[t.entity][t.expect]?(t.entity===a.ConnectionEnd.server&&!t.open&&!t.fail&&(t.handshaking=!0,t.session={version:null,extensions:{server_name:{serverNameList:[]}},cipherSuite:null,compressionMethod:null,serverCertificate:null,clientCertificate:null,md5:e.md.md5.create(),sha1:e.md.sha1.create()}),i!==a.HandshakeType.hello_request&&i!==a.HandshakeType.certificate_verify&&i!==a.HandshakeType.finished&&(t.session.md5.update(o),t.session.sha1.update(o)),q[t.entity][t.expect][i](t,n,s)):a.handleUnexpected(t,n)},a.handleApplicationData=function(e,t){e.data.putBuffer(t.fragment),e.dataReady(e),e.process()},a.handleHeartbeat=function(t,n){var r=n.fragment,i=r.getByte(),s=r.getInt16(),o=r.getBytes(s);if(i===a.HeartbeatMessageType.heartbeat_request){if(t.handshaking||s>o.length)return t.process();a.queue(t,a.createRecord(t,{type:a.ContentType.heartbeat,data:a.createHeartbeat(a.HeartbeatMessageType.heartbeat_response,o)})),a.flush(t)}else if(i===a.HeartbeatMessageType.heartbeat_response){if(o!==t.expectedHeartbeatPayload)return t.process();t.heartbeatReceived&&t.heartbeatReceived(t,e.util.createBuffer(o))}t.process()};var f=0,l=1,c=2,h=3,p=4,d=5,v=6,m=7,g=8,y=0,b=1,w=2,E=3,S=4,x=5,T=6,N=7,C=a.handleUnexpected,k=a.handleChangeCipherSpec,L=a.handleAlert,A=a.handleHandshake,O=a.handleApplicationData,M=a.handleHeartbeat,_=[];_[a.ConnectionEnd.client]=[[C,L,A,C,M],[C,L,A,C,M],[C,L,A,C,M],[C,L,A,C,M],[C,L,A,C,M],[k,L,C,C,M],[C,L,A,C,M],[C,L,A,O,M],[C,L,A,C,M]],_[a.ConnectionEnd.server]=[[C,L,A,C,M],[C,L,A,C,M],[C,L,A,C,M],[C,L,A,C,M],[k,L,C,C,M],[C,L,A,C,M],[C,L,A,O,M],[C,L,A,C,M]];var D=a.handleHelloRequest,P=a.handleServerHello,H=a.handleCertificate,B=a.handleServerKeyExchange,j=a.handleCertificateRequest,F=a.handleServerHelloDone,I=a.handleFinished,q=[];q[a.ConnectionEnd.client]=[[C,C,P,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[D,C,C,C,C,C,C,C,C,C,C,H,B,j,F,C,C,C,C,C,C],[D,C,C,C,C,C,C,C,C,C,C,C,B,j,F,C,C,C,C,C,C],[D,C,C,C,C,C,C,C,C,C,C,C,C,j,F,C,C,C,C,C,C],[D,C,C,C,C,C,C,C,C,C,C,C,C,C,F,C,C,C,C,C,C],[D,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[D,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,I],[D,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[D,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C]];var R=a.handleClientHello,U=a.handleClientKeyExchange,z=a.handleCertificateVerify;q[a.ConnectionEnd.server]=[[C,R,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,H,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,U,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,z,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,I],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C],[C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C,C]],a.generateKeys=function(e,n){var r=t,i=n.client_random+n.server_random;e.session.resuming||(n.master_secret=r(n.pre_master_secret,"master secret",i,48).bytes(),n.pre_master_secret=null),i=n.server_random+n.client_random;var s=2*n.mac_key_length+2*n.enc_key_length,o=e.version.major===a.Versions.TLS_1_0.major&&e.version.minor===a.Versions.TLS_1_0.minor;o&&(s+=2*n.fixed_iv_length);var u=r(n.master_secret,"key expansion",i,s),f={client_write_MAC_key:u.getBytes(n.mac_key_length),server_write_MAC_key:u.getBytes(n.mac_key_length),client_write_key:u.getBytes(n.enc_key_length),server_write_key:u.getBytes(n.enc_key_length)};return o&&(f.client_write_IV=u.getBytes(n.fixed_iv_length),f.server_write_IV=u.getBytes(n.fixed_iv_length)),f},a.createConnectionState=function(e){var t=e.entity===a.ConnectionEnd.client,n=function(){var e={sequenceNumber:[0,0],macKey:null,macLength:0,macFunction:null,cipherState:null,cipherFunction:function(e){return!0},compressionState:null,compressFunction:function(e){return!0},updateSequenceNumber:function(){e.sequenceNumber[1]===4294967295?(e.sequenceNumber[1]=0,++e.sequenceNumber[0]):++e.sequenceNumber[1]}};return e},r={read:n(),write:n()};r.read.update=function(e,t){return r.read.cipherFunction(t,r.read)?r.read.compressFunction(e,t,r.read)||e.error(e,{message:"Could not decompress record.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.decompression_failure}}):e.error(e,{message:"Could not decrypt record or bad MAC.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.bad_record_mac}}),!e.fail},r.write.update=function(e,t){return r.write.compressFunction(e,t,r.write)?r.write.cipherFunction(t,r.write)||e.error(e,{message:"Could not encrypt record.",send:!1,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}}):e.error(e,{message:"Could not compress record.",send:!1,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}}),!e.fail};if(e.session){var o=e.session.sp;e.session.cipherSuite.initSecurityParameters(o),o.keys=a.generateKeys(e,o),r.read.macKey=t?o.keys.server_write_MAC_key:o.keys.client_write_MAC_key,r.write.macKey=t?o.keys.client_write_MAC_key:o.keys.server_write_MAC_key,e.session.cipherSuite.initConnectionState(r,e,o);switch(o.compression_algorithm){case a.CompressionMethod.none:break;case a.CompressionMethod.deflate:r.read.compressFunction=s,r.write.compressFunction=i;break;default:throw{message:"Unsupported compression algorithm."}}}return r},a.createRandom=function(){var t=new Date,n=+t+t.getTimezoneOffset()*6e4,r=e.util.createBuffer();return r.putInt32(n),r.putBytes(e.random.getBytes(28)),r},a.createRecord=function(e,t){if(!t.data)return null;var n={type:t.type,version:{major:e.version.major,minor:e.version.minor},length:t.data.length(),fragment:t.data};return n},a.createAlert=function(t,n){var r=e.util.createBuffer();return r.putByte(n.level),r.putByte(n.description),a.createRecord(t,{type:a.ContentType.alert,data:r})},a.createClientHello=function(t){t.session.clientHelloVersion={major:t.version.major,minor:t.version.minor};var n=e.util.createBuffer();for(var r=0;r0&&(d+=2);var v=t.session.id,m=v.length+1+2+4+28+2+s+1+f+d,g=e.util.createBuffer();return g.putByte(a.HandshakeType.client_hello),g.putInt24(m),g.putByte(t.version.major),g.putByte(t.version.minor),g.putBytes(t.session.sp.client_random),u(g,1,e.util.createBuffer(v)),u(g,2,n),u(g,1,o),d>0&&u(g,2,l),g},a.createServerHello=function(t){var n=t.session.id,r=n.length+1+2+4+28+2+1,i=e.util.createBuffer();return i.putByte(a.HandshakeType.server_hello),i.putInt24(r),i.putByte(t.version.major),i.putByte(t.version.minor),i.putBytes(t.session.sp.server_random),u(i,1,e.util.createBuffer(n)),i.putByte(t.session.cipherSuite.id[0]),i.putByte(t.session.cipherSuite.id[1]),i.putByte(t.session.compressionMethod),i},a.createCertificate=function(t){var n=t.entity===a.ConnectionEnd.client,r=null;if(t.getCertificate){var i;n?i=t.session.certificateRequest:i=t.session.extensions.server_name.serverNameList,r=t.getCertificate(t,i)}var s=e.util.createBuffer();if(r!==null)try{e.util.isArray(r)||(r=[r]);var o=null;for(var f=0;f0&&(r.putByte(a.HandshakeType.server_key_exchange),r.putInt24(n)),r},a.getClientSignature=function(t,n){var r=e.util.createBuffer();r.putBuffer(t.session.md5.digest()),r.putBuffer(t.session.sha1.digest()),r=r.getBytes(),t.getSignature=t.getSignature||function(t,n,r){var i=null;if(t.getPrivateKey)try{i=t.getPrivateKey(t,t.session.clientCertificate),i=e.pki.privateKeyFromPem(i)}catch(s){t.error(t,{message:"Could not get private key.",cause:s,send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}})}i===null?t.error(t,{message:"No private key set.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.internal_error}}):n=i.sign(n,null),r(t,n)},t.getSignature(t,r,n)},a.createCertificateVerify=function(t,n){var r=n.length+2,i=e.util.createBuffer();return i.putByte(a.HandshakeType.certificate_verify),i.putInt24(r),i.putInt16(n.length),i.putBytes(n),i},a.createCertificateRequest=function(t){var n=e.util.createBuffer();n.putByte(1);var r=e.util.createBuffer();for(var i in t.caStore.certs){var s=t.caStore.certs[i],o=e.pki.distinguishedNameToAsn1(s.subject);r.putBuffer(e.asn1.toDer(o))}var f=1+n.length()+2+r.length(),l=e.util.createBuffer();return l.putByte(a.HandshakeType.certificate_request),l.putInt24(f),u(l,1,n),u(l,2,r),l},a.createServerHelloDone=function(t){var n=e.util.createBuffer();return n.putByte(a.HandshakeType.server_hello_done),n.putInt24(0),n},a.createChangeCipherSpec=function(){var t=e.util.createBuffer();return t.putByte(1),t},a.createFinished=function(n){var r=e.util.createBuffer();r.putBuffer(n.session.md5.digest()),r.putBuffer(n.session.sha1.digest());var i=n.entity===a.ConnectionEnd.client,s=n.session.sp,o=12,u=t,f=i?"client finished":"server finished";r=u(s.master_secret,f,r.getBytes(),o);var l=e.util.createBuffer();return l.putByte(a.HandshakeType.finished),l.putInt24(r.length()),l.putBuffer(r),l},a.createHeartbeat=function(t,n,r){typeof r=="undefined"&&(r=n.length);var i=e.util.createBuffer();i.putByte(t),i.putInt16(r),i.putBytes(n);var s=i.length(),o=Math.max(16,s-r-3);return i.putBytes(e.random.getBytes(o)),i},a.queue=function(t,n){if(!n)return;if(n.type===a.ContentType.handshake){var r=n.fragment.bytes();t.session.md5.update(r),t.session.sha1.update(r),r=null}var i;if(n.fragment.length()<=a.MaxFragment)i=[n];else{i=[];var s=n.fragment.bytes();while(s.length>a.MaxFragment)i.push(a.createRecord(t,{type:n.type,data:e.util.createBuffer(s.slice(0,a.MaxFragment))})),s=s.slice(a.MaxFragment);s.length>0&&i.push(a.createRecord(t,{type:n.type,data:e.util.createBuffer(s)}))}for(var o=0;o0&&(i=r.order[0]);if(i!==null&&i in r.cache){n=r.cache[i],delete r.cache[i];for(var s in r.order)if(r.order[s]===i){r.order.splice(s,1);break}}return n},r.setSession=function(t,n){if(r.order.length===r.capacity){var i=r.order.shift();delete r.cache[i]}var i=e.util.bytesToHex(t);r.order.push(i),r.cache[i]=n}}return r},a.createConnection=function(t){var n=null;t.caStore?e.util.isArray(t.caStore)?n=e.pki.createCaStore(t.caStore):n=t.caStore:n=e.pki.createCaStore();var r=t.cipherSuites||null;if(r===null){r=[];for(var i in a.CipherSuites)r.push(a.CipherSuites[i])}var s=t.server||!1?a.ConnectionEnd.server:a.ConnectionEnd.client,o=t.sessionCache?a.createSessionCache(t.sessionCache):null,u={version:{major:a.Version.major,minor:a.Version.minor},entity:s,sessionId:t.sessionId,caStore:n,sessionCache:o,cipherSuites:r,connected:t.connected,virtualHost:t.virtualHost||null,verifyClient:t.verifyClient||!1,verify:t.verify||function(e,t,n,r){return t},getCertificate:t.getCertificate||null,getPrivateKey:t.getPrivateKey||null,getSignature:t.getSignature||null,input:e.util.createBuffer(),tlsData:e.util.createBuffer(),data:e.util.createBuffer(),tlsDataReady:t.tlsDataReady,dataReady:t.dataReady,heartbeatReceived:t.heartbeatReceived,closed:t.closed,error:function(e,n){n.origin=n.origin||(e.entity===a.ConnectionEnd.client?"client":"server"),n.send&&(a.queue(e,a.createAlert(e,n.alert)),a.flush(e));var r=n.fatal!==!1;r&&(e.fail=!0),t.error(e,n),r&&e.close(!1)},deflate:t.deflate||null,inflate:t.inflate||null};u.reset=function(e){u.version={major:a.Version.major,minor:a.Version.minor},u.record=null,u.session=null,u.peerCertificate=null,u.state={pending:null,current:null},u.expect=u.entity===a.ConnectionEnd.client?f:y,u.fragmented=null,u.records=[],u.open=!1,u.handshakes=0,u.handshaking=!1,u.isConnected=!1,u.fail=!e&&typeof e!="undefined",u.input.clear(),u.tlsData.clear(),u.data.clear(),u.state.current=a.createConnectionState(u)},u.reset();var l=function(e,t){var n=t.type-a.ContentType.change_cipher_spec,r=_[e.entity][e.expect];n in r?r[n](e,t):a.handleUnexpected(e,t)},c=function(t){var n=0,r=t.input,i=r.length();if(i<5)n=5-i;else{t.record={type:r.getByte(),version:{major:r.getByte(),minor:r.getByte()},length:r.getInt16(),fragment:e.util.createBuffer(),ready:!1};var s=t.record.version.major===t.version.major;s&&t.session&&t.session.version&&(s=t.record.version.minor===t.version.minor),s||t.error(t,{message:"Incompatible TLS version.",send:!0,alert:{level:a.Alert.Level.fatal,description:a.Alert.Description.protocol_version}})}return n},h=function(e){var t=0,n=e.input,r=n.length();if(r0&&(u.sessionCache&&(n=u.sessionCache.getSession(t)),n===null&&(t="")),t.length===0&&u.sessionCache&&(n=u.sessionCache.getSession(),n!==null&&(t=n.id)),u.session={id:t,version:null,cipherSuite:null,compressionMethod:null,serverCertificate:null,certificateRequest:null,clientCertificate:null,sp:{},md5:e.md.md5.create(),sha1:e.md.sha1.create()},n&&(u.version=n.version,u.session.sp=n.sp),u.session.sp.client_random=a.createRandom().getBytes(),u.open=!0,a.queue(u,a.createRecord(u,{type:a.ContentType.handshake,data:a.createClientHello(u)})),a.flush(u)}},u.process=function(e){var t=0;return e&&u.input.putBytes(e),u.fail||(u.record!==null&&u.record.ready&&u.record.fragment.isEmpty()&&(u.record=null),u.record===null&&(t=c(u)),!u.fail&&u.record!==null&&!u.record.ready&&(t=h(u)),!u.fail&&u.record!==null&&u.record.ready&&l(u,u.record)),t},u.prepare=function(t){return a.queue(u,a.createRecord(u,{type:a.ContentType.application_data,data:e.util.createBuffer(t)})),a.flush(u)},u.prepareHeartbeatRequest=function(t,n){return t instanceof e.util.ByteBuffer&&(t=t.bytes()),typeof n=="undefined"&&(n=t.length),u.expectedHeartbeatPayload=t,a.queue(u,a.createRecord(u,{type:a.ContentType.heartbeat,data:a.createHeartbeat(a.HeartbeatMessageType.heartbeat_request,t,n)})),a.flush(u)},u.close=function(e){if(!u.fail&&u.sessionCache&&u.session){var t={id:u.session.id,version:u.session.version,sp:u.session.sp};t.sp.keys=null,u.sessionCache.setSession(t.id,t)}if(u.open){u.open=!1,u.input.clear();if(u.isConnected||u.handshaking)u.isConnected=u.handshaking=!1,a.queue(u,a.createAlert(u,{level:a.Alert.Level.warning,description:a.Alert.Description.close_notify})),a.flush(u);u.closed(u)}u.reset(e)},u},e.tls=e.tls||{};for(var V in a)typeof a[V]!="function"&&(e.tls[V]=a[V]);e.tls.prf_tls1=t,e.tls.hmac_sha1=r,e.tls.createSessionCache=a.createSessionCache,e.tls.createConnection=a.createConnection}var r="tls";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=t.Versions.TLS_1_1.minor&&a.output.putBytes(u),a.update(n.fragment),a.finish(i)&&(n.fragment=a.output,n.length=n.fragment.length(),s=!0),s}function i(e,t,n){if(!n){var r=e-t.length()%e;t.fillWithByte(r-1,r)}return!0}function s(e,t,n){var r=!0;if(n){var i=t.length(),s=t.last();for(var o=i-1-s;o=f?(n.fragment=a.output.getBytes(h-f),l=a.output.getBytes(f)):n.fragment=a.output.getBytes(),n.fragment=e.util.createBuffer(n.fragment),n.length=n.fragment.length();var p=r.macFunction(r.macKey,r.sequenceNumber,n);return r.updateSequenceNumber(),i=p===l&&i,i}var t=e.tls;t.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA={id:[0,47],name:"TLS_RSA_WITH_AES_128_CBC_SHA",initSecurityParameters:function(e){e.bulk_cipher_algorithm=t.BulkCipherAlgorithm.aes,e.cipher_type=t.CipherType.block,e.enc_key_length=16,e.block_length=16,e.fixed_iv_length=16,e.record_iv_length=16,e.mac_algorithm=t.MACAlgorithm.hmac_sha1,e.mac_length=20,e.mac_key_length=20},initConnectionState:n},t.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA={id:[0,53],name:"TLS_RSA_WITH_AES_256_CBC_SHA",initSecurityParameters:function(e){e.bulk_cipher_algorithm=t.BulkCipherAlgorithm.aes,e.cipher_type=t.CipherType.block,e.enc_key_length=32,e.block_length=16,e.fixed_iv_length=16,e.record_iv_length=16,e.mac_algorithm=t.MACAlgorithm.hmac_sha1,e.mac_length=20,e.mac_key_length=20},initConnectionState:n};var o=0}var r="aesCipherSuites";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o=1&&e.log.verbose(t,"[%s][%s] init",this.id,this.name,this)};T.prototype.debug=function(n){n=n||"",e.log.debug(t,n,"[%s][%s] task:",this.id,this.name,this,"subtasks:",this.subtasks.length,"queue:",s)},T.prototype.next=function(e,t){typeof e=="function"&&(t=e,e=this.name);var n=new T({run:t,name:e,parent:this});return n.state=l,n.type=this.type,n.successCallback=this.successCallback||null,n.failureCallback=this.failureCallback||null,this.subtasks.push(n),this},T.prototype.parallel=function(t,n){return e.util.isArray(t)&&(n=t,t=this.name),this.next(t,function(r){var i=r;i.block(n.length);var s=function(t,r){e.task.start({type:t,run:function(e){n[r](e)},success:function(e){i.unblock()},failure:function(e){i.unblock()}})};for(var o=0;o0&&(this.state=x[this.state][g])},T.prototype.unblock=function(e){return e=typeof e=="undefined"?1:e,this.blocks-=e,this.blocks===0&&this.state!==p&&(this.state=l,C(this,0)),this.blocks},T.prototype.sleep=function(e){e=typeof e=="undefined"?0:e,this.state=x[this.state][b];var t=this;this.timeoutId=setTimeout(function(){t.timeoutId=null,t.state=l,C(t,0)},e)},T.prototype.wait=function(e){e.wait(this)},T.prototype.wakeup=function(){this.state===h&&(cancelTimeout(this.timeoutId),this.timeoutId=null,this.state=l,C(this,0))},T.prototype.cancel=function(){this.state=x[this.state][E],this.permitsNeeded=0,this.timeoutId!==null&&(cancelTimeout(this.timeoutId),this.timeoutId=null),this.subtasks=[]},T.prototype.fail=function(e){this.error=!0,k(this,!0);if(e)e.error=this.error,e.swapTime=this.swapTime,e.userData=this.userData,C(e,0);else{if(this.parent!==null){var t=this.parent;while(t.parent!==null)t.error=this.error,t.swapTime=this.swapTime,t.userData=this.userData,t=t.parent;k(t,!0)}this.failureCallback&&this.failureCallback(this)}};var N=function(e){e.error=!1,e.state=x[e.state][m],setTimeout(function(){e.state===l&&(e.swapTime=+(new Date),e.run(e),C(e,0))},0)},C=function(e,t){var n=t>u||+(new Date)-e.swapTime>a,r=function(t){t++;if(e.state===l){n&&(e.swapTime=+(new Date));if(e.subtasks.length>0){var r=e.subtasks.shift();r.error=e.error,r.swapTime=e.swapTime,r.userData=e.userData,r.run(r),r.error||C(r,t)}else k(e),e.error||e.parent!==null&&(e.parent.error=e.error,e.parent.swapTime=e.swapTime,e.parent.userData=e.userData,C(e.parent,t))}};n?setTimeout(r,0):r(t)},k=function(i,o){i.state=p,delete r[i.id],n>=1&&e.log.verbose(t,"[%s][%s] finish",i.id,i.name,i),i.parent===null&&(i.type in s?s[i.type].length===0?e.log.error(t,"[%s][%s] task queue empty [%s]",i.id,i.name,i.type):s[i.type][0]!==i?e.log.error(t,"[%s][%s] task not first in queue [%s]",i.id,i.name,i.type):(s[i.type].shift(),s[i.type].length===0?(n>=1&&e.log.verbose(t,"[%s][%s] delete queue [%s]",i.id,i.name,i.type),delete s[i.type]):(n>=1&&e.log.verbose(t,"[%s][%s] queue start next [%s] remain:%s",i.id,i.name,i.type,s[i.type].length),s[i.type][0].start())):e.log.error(t,"[%s][%s] task queue missing [%s]",i.id,i.name,i.type),o||(i.error&&i.failureCallback?i.failureCallback(i):!i.error&&i.successCallback&&i.successCallback(i)))};e.task=e.task||{},e.task.start=function(r){var i=new T({run:r.run,name:r.name||o});i.type=r.type,i.successCallback=r.success||null,i.failureCallback=r.failure||null,i.type in s?s[r.type].push(i):(n>=1&&e.log.verbose(t,"[%s][%s] create queue [%s]",i.id,i.name,i.type),s[i.type]=[i],N(i))},e.task.cancel=function(e){e in s&&(s[e]=[s[e][0]])},e.task.createCondition=function(){var e={tasks:{}};return e.wait=function(t){t.id in e.tasks||(t.block(),e.tasks[t.id]=t)},e.notify=function(){var t=e.tasks;e.tasks={};for(var n in t)t[n].unblock()},e}}var r="task";if(typeof n!="function"){if(typeof module!="object"||!module.exports)return typeof forge=="undefined"&&(forge={}),e(forge);var i=!0;n=function(e,n){n(t,module)}}var s,o=function(t,n){n.exports=function(n){var i=s.map(function(e){return t(e)}).concat(e);n=n||{},n.defined=n.defined||{};if(n.defined[r])return n[r];n.defined[r]=!0;for(var o=0;o="8"&&(r="00"+r);var i=e.util.hexToBytes(r);t.putInt32(i.length),t.putBytes(i)}function r(e,t){e.putInt32(t.length),e.putString(t)}function i(){var t=e.md.sha1.create(),n=arguments.length;for(var r=0;r>=1,0===I&&(I=b(),a=1&I,I=I>>1|128),a}function e(a){for(var b=0,c=a;c--;)b=b<<1|d();return a&&(b=A[b]>>8-a),b}function f(){y=0}function g(a){r++,x[y++]=a,t.push(String.fromCharCode(a)),32768==y&&(y=0)}function h(){this.b0=0,this.b1=0,this.jump=null,this.jumppos=-1}function i(){for(;;){if(S[R]>=U)return-1;if(T[S[R]]==R)return S[R]++;S[R]++}}function j(){var a,b=Q[P];if(u&&document.write("
len:"+R+" treepos:"+P),17==R)return-1;if(P++,R++,a=i(),u&&document.write("
IsPat "+a),a>=0)b.b0=a,u&&document.write("
b0 "+b.b0);else if(b.b0=32768,u&&document.write("
b0 "+b.b0),j())return-1;if(a=i(),a>=0)b.b1=a,u&&document.write("
b1 "+b.b1),b.jump=null;else if(b.b1=32768,u&&document.write("
b1 "+b.b1),b.jump=Q[P],b.jumppos=P,j())return-1;return R--,0}function k(a,b,c,d){var e;for(u&&document.write("currentTree "+a+" numval "+b+" lengths "+c+" show "+d),Q=a,P=0,T=c,U=b,e=0;17>e;e++)S[e]=0;if(R=0,j())return u&&alert("invalid huffman tree\n"),-1;if(u){document.write("
Tree: "+Q.length);for(var f=0;32>f;f++)document.write("Places["+f+"].b0="+Q[f].b0+"
"),document.write("Places["+f+"].b1="+Q[f].b1+"
")}return 0}function l(a){for(var b,c,e,f=0,g=a[f];;)if(e=d(),u&&document.write("b="+e),e){if(!(32768&g.b1))return u&&document.write("ret1"),g.b1;for(g=g.jump,b=a.length,c=0;b>c;c++)if(a[c]===g){f=c;break}}else{if(!(32768&g.b0))return u&&document.write("ret2"),g.b0;f++,g=a[f]}}function m(){var a,i,j,m,n,o,p;do{switch(a=d(),j=e(2)){case 0:u&&alert("Stored\n");break;case 1:u&&alert("Fixed Huffman codes\n");break;case 2:u&&alert("Dynamic Huffman codes\n");break;case 3:u&&alert("Reserved block type!!\n");break;default:u&&alert("Unexpected value %d!\n",j)}if(0===j){var q,r;for(c(),q=b(),q|=b()<<8,r=b(),r|=b()<<8,65535&(q^~r)&&document.write("BlockLen checksum mismatch\n");q--;)i=b(),g(i)}else if(1==j)for(;;)if(n=A[e(7)]>>1,n>23?(n=n<<1|d(),n>199?(n-=128,n=n<<1|d()):(n-=48,n>143&&(n+=136))):n+=256,256>n)g(n);else{if(256==n)break;for(n-=257,o=e(C[n])+B[n],n=A[e(5)]>>3,E[n]>8?(p=e(8),p|=e(E[n]-8)<<8):p=e(E[n]),p+=D[n],n=0;o>n;n++)i=x[y-p&32767],g(i)}else if(2==j){var s,t,v,w,z=new Array(320);for(t=257+e(5),v=1+e(5),w=4+e(4),n=0;19>n;n++)z[n]=0;for(n=0;w>n;n++)z[F[n]]=e(3);for(o=O.length,m=0;o>m;m++)O[m]=new h;if(k(O,19,z,0))return f(),1;if(u){document.write("
distanceTree");for(var G=0;G"+O[G].b0+" "+O[G].b1+" "+O[G].jump+" "+O[G].jumppos)}s=t+v,m=0;var H=-1;for(u&&document.write("
n="+s+" bits: "+J+"
");s>m;)if(H++,n=l(O),u&&document.write("
"+H+" i:"+m+" decode: "+n+" bits "+J+"
"),16>n)z[m++]=n;else if(16==n){var I;if(n=3+e(2),m+n>s)return f(),1;for(I=m?z[m-1]:0;n--;)z[m++]=I}else{if(n=17==n?3+e(3):11+e(7),m+n>s)return f(),1;for(;n--;)z[m++]=0}for(o=N.length,m=0;o>m;m++)N[m]=new h;if(k(N,t,z,0))return f(),1;for(o=N.length,m=0;o>m;m++)O[m]=new h;var K=[];for(m=t;mliteralTree");a:for(;;)if(n=l(N),n>=256){if(n-=256,0===n)break;for(n--,o=e(C[n])+B[n],n=l(O),E[n]>8?(p=e(8),p|=e(E[n]-8)<<8):p=e(E[n]),p+=D[n];o--;){if(0>y-p)break a;i=x[y-p&32767],g(i)}}else g(n)}}while(!a);return f(),c(),0}function n(){u&&alert("NEXTFILE"),t=[];var a=[];if(z=!1,a[0]=b(),a[1]=b(),u&&alert("type: "+a[0]+" "+a[1]),a[0]==parseInt("78",16)&&a[1]==parseInt("da",16)&&(u&&alert("GEONExT-GZIP"),m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="geonext.gxt",v++),a[0]==parseInt("78",16)&&a[1]==parseInt("9c",16)&&(u&&alert("ZLIB"),m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="ZLIB",v++),a[0]==parseInt("1f",16)&&a[1]==parseInt("8b",16)&&(u&&alert("GZIP"),o(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="file",v++),a[0]==parseInt("50",16)&&a[1]==parseInt("4b",16)&&(z=!0,a[2]=b(),a[3]=b(),a[2]==parseInt("3",16)&&a[3]==parseInt("4",16))){a[0]=b(),a[1]=b(),u&&alert("ZIP-Version: "+a[1]+" "+a[0]/10+"."+a[0]%10),p=b(),p|=b()<<8,u&&alert("gpflags: "+p);var c=b();c|=b()<<8,u&&alert("method: "+c),b(),b(),b(),b();var d=b();d|=b()<<8,d|=b()<<16,d|=b()<<24;var e=b();e|=b()<<8,e|=b()<<16,e|=b()<<24;var f=b();f|=b()<<8,f|=b()<<16,f|=b()<<24,u&&alert("local CRC: "+d+"\nlocal Size: "+f+"\nlocal CompSize: "+e);var g=b();g|=b()<<8;var h=b();h|=b()<<8,u&&alert("filelen "+g),j=0,L=[];for(var i;g--;)i=b(),"/"==i|":"==i?j=0:K-1>j&&(L[j++]=String.fromCharCode(i));u&&alert("nameBuf: "+L),s||(s=L);for(var j=0;h>j;)i=b(),j++;q=4294967295,r=0,0===f&&"/"==fileOut.charAt(s.length-1)&&u&&alert("skipdir"),8==c&&(m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]=L.join(""),v++),o()}}function o(){var a,c,d,e,f,g,h=[];if(8&p&&(h[0]=b(),h[1]=b(),h[2]=b(),h[3]=b(),h[0]==parseInt("50",16)&&h[1]==parseInt("4b",16)&&h[2]==parseInt("07",16)&&h[3]==parseInt("08",16)?(a=b(),a|=b()<<8,a|=b()<<16,a|=b()<<24):a=h[0]|h[1]<<8|h[2]<<16|h[3]<<24,c=b(),c|=b()<<8,c|=b()<<16,c|=b()<<24,d=b(),d|=b()<<8,d|=b()<<16,d|=b()<<24,u&&alert("CRC:")),z&&n(),h[0]=b(),8!=h[0])return u&&alert("Unknown compression method!"),0;if(p=b(),u&&p&~parseInt("1f",16)&&alert("Unknown flags set!"),b(),b(),b(),b(),b(),e=b(),4&p)for(h[0]=b(),h[2]=b(),R=h[0]+256*h[1],u&&alert("Extra field size: "+R),f=0;R>f;f++)b();if(8&p){for(f=0,L=[];g=b();)("7"==g||":"==g)&&(f=0),K-1>f&&(L[f++]=g);u&&alert("original file name: "+L)}if(16&p)for(;g=b(););2&p&&(b(),b()),m(),a=b(),a|=b()<<8,a|=b()<<16,a|=b()<<24,d=b(),d|=b()<<8,d|=b()<<16,d|=b()<<24,z&&n()}var p,q,r,s,t=[],u=!1,v=0,w=[],x=new Array(32768),y=0,z=!1,A=[0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248,4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251,7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255],B=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],C=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],D=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],E=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],F=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],G=a,H=0,I=1,J=0,K=256,L=[],M=288,N=new Array(M),O=new Array(32),P=0,Q=null,R=(new Array(64),new Array(64),0),S=new Array(17);S[0]=0;var T,U;JXG.Util.Unzip.prototype.unzipFile=function(a){var b;for(this.unzip(),b=0;b>2,f=(3&b)<<4|c>>4,g=(15&c)<<2|d>>6,h=63&d,isNaN(c)?g=h=64:isNaN(d)&&(h=64),i.push([this._keyStr.charAt(e),this._keyStr.charAt(f),this._keyStr.charAt(g),this._keyStr.charAt(h)].join(""));return i.join("")},decode:function(a,b){var c,d,e,f,g,h,i,j=[],k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,j.push(String.fromCharCode(c)),64!=h&&j.push(String.fromCharCode(d)),64!=i&&j.push(String.fromCharCode(e));return j=j.join(""),b&&(j=JXG.Util.Base64._utf8_decode(j)),j},_utf8_encode:function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;cd?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(d>>6|192),b+=String.fromCharCode(63&d|128)):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128),b+=String.fromCharCode(63&d|128))}return b},_utf8_decode:function(a){for(var b=[],c=0,d=0,e=0,f=0;cd?(b.push(String.fromCharCode(d)),c++):d>191&&224>d?(e=a.charCodeAt(c+1),b.push(String.fromCharCode((31&d)<<6|63&e)),c+=2):(e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b.push(String.fromCharCode((15&d)<<12|(63&e)<<6|63&f)),c+=3);return b.join("")},_destrip:function(a,b){var c,d,e=[],f=[];for(null===b&&(b=76),a.replace(/ /g,""),c=a.length/b,d=0;c>d;d++)e[d]=a.substr(d*b,b);for(c!=a.length/b&&(e[e.length]=a.substr(c*b,a.length-c*b)),d=0;d255)switch(c){case 8364:c=128;break;case 8218:c=130;break;case 402:c=131;break;case 8222:c=132;break;case 8230:c=133;break;case 8224:c=134;break;case 8225:c=135;break;case 710:c=136;break;case 8240:c=137;break;case 352:c=138;break;case 8249:c=139;break;case 338:c=140;break;case 381:c=142;break;case 8216:c=145;break;case 8217:c=146;break;case 8220:c=147;break;case 8221:c=148;break;case 8226:c=149;break;case 8211:c=150;break;case 8212:c=151;break;case 732:c=152;break;case 8482:c=153;break;case 353:c=154;break;case 8250:c=155;break;case 339:c=156;break;case 382:c=158;break;case 376:c=159}return c},JXG.Util.utf8Decode=function(a){var b,c=[],d=0,e=0,f=0;if(!JXG.exists(a))return"";for(;de?(c.push(String.fromCharCode(e)),d++):e>191&&224>e?(f=a.charCodeAt(d+1),c.push(String.fromCharCode((31&e)<<6|63&f)),d+=2):(f=a.charCodeAt(d+1),b=a.charCodeAt(d+2),c.push(String.fromCharCode((15&e)<<12|(63&f)<<6|63&b)),d+=3);return c.join("")},JXG.Util.genUUID=function(){for(var a,b="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),c=new Array(36),d=0,e=0;36>e;e++)8==e||13==e||18==e||23==e?c[e]="-":14==e?c[e]="4":(2>=d&&(d=33554432+16777216*Math.random()|0),a=15&d,d>>=4,c[e]=b[19==e?3&a|8:a]);return c.join("")},b.exports=JXG},{}],3:[function(a,b){var c=a("../enums.js");b.exports={prefer_hash_algorithm:c.hash.sha256,encryption_cipher:c.symmetric.aes256,compression:c.compression.zip,integrity_protect:!0,rsa_blinding:!0,show_version:!0,show_comment:!0,versionstring:"OpenPGP.js v0.5.1",commentstring:"http://openpgpjs.org",keyserver:"keyserver.linux.it",node_store:"./openpgp.store",debug:!1}},{"../enums.js":30}],4:[function(a,b){b.exports=a("./config.js")},{"./config.js":3}],5:[function(a,b){"use strict";var c=a("../util.js"),d=a("./cipher");b.exports={encrypt:function(a,b,e,f,g){b=new d[b](f);var h=b.blockSize,i=new Uint8Array(h),j=new Uint8Array(h);a=a+a.charAt(h-2)+a.charAt(h-1),c.print_debug("prefixrandom:"+c.hexstrdump(a));var k,l,m="";for(k=0;h>k;k++)i[k]=0;for(j=b.encrypt(i),k=0;h>k;k++)m+=String.fromCharCode(j[k]^a.charCodeAt(k));for(k=0;h>k;k++)i[k]=m.charCodeAt(k);if(j=b.encrypt(i),m+=String.fromCharCode(j[0]^a.charCodeAt(h)),m+=String.fromCharCode(j[1]^a.charCodeAt(h+1)),g)for(k=0;h>k;k++)i[k]=m.charCodeAt(k+2);else for(k=0;h>k;k++)i[k]=m.charCodeAt(k);if(j=b.encrypt(i),g){for(k=0;h>k;k++)m+=String.fromCharCode(j[k]^e.charCodeAt(k));for(l=h+2;lk;k++)i[k]=m.charCodeAt(l+k);for(j=b.encrypt(i),k=0;h>k;k++)m+=String.fromCharCode(j[k]^e.charCodeAt(l-2+k))}}else{for(e=" "+e,k=2;h>k;k++)m+=String.fromCharCode(j[k]^e.charCodeAt(k));var n,o=m.substring(0,2*h),p=m.substring(h);for(l=h;lk;k++)i[k]=p.charCodeAt(k);for(p="",j=b.encrypt(i),k=0;h>k;k++)n=String.fromCharCode(j[k]^e.charCodeAt(l+k)),o+=n,p+=n}m=o}return m=m.substring(0,e.length+2+h)},mdc:function(a,b,e){a=new d[a](b);var f,g=a.blockSize,h=new Uint8Array(g),i=new Uint8Array(g);for(f=0;g>f;f++)h[f]=0;for(h=a.encrypt(h),f=0;g>f;f++)i[f]=e.charCodeAt(f),h[f]^=i[f];return i=a.encrypt(i),c.bin2str(h)+String.fromCharCode(i[0]^e.charCodeAt(g))+String.fromCharCode(i[1]^e.charCodeAt(g+1))},decrypt:function(a,b,c,e){a=new d[a](b);var f,g=a.blockSize,h=new Uint8Array(g),i=new Uint8Array(g),j="",k="";for(f=0;g>f;f++)h[f]=0;for(h=a.encrypt(h),f=0;g>f;f++)i[f]=c.charCodeAt(f),h[f]^=i[f];if(i=a.encrypt(i),h[g-2]!=(i[0]^c.charCodeAt(g))||h[g-1]!=(i[1]^c.charCodeAt(g+1)))throw new Error("Invalid data.");if(e){for(f=0;g>f;f++)h[f]=c.charCodeAt(f+2);for(j=g+2;jf&&f+jf;f++)h[f]=c.charCodeAt(f);for(j=g;jf&&f+jg*j;){var m=a.encrypt(c.str2bin(i));h=e.substring(j*g,j*g+g);for(var n=0;ng;g++)i+=String.fromCharCode(0);else i=f.substring(0,h);for(;e.length>h*j;){var m=a.encrypt(c.str2bin(i));for(i=e.substring(j*h+l,j*h+h+l),g=0;g>8&255}function e(a){return a>>16&255}function f(a){return a>>24&255}function g(a,b,c,e){return d(o[255&a])|d(o[b>>8&255])<<8|d(o[c>>16&255])<<16|d(o[e>>>24])<<24}function h(a){var b,c,d=a.length,e=new Array(d/4);if(a&&!(d%4)){for(b=0,c=0;d>c;c+=4)e[b++]=a[c]|a[c+1]<<8|a[c+2]<<16|a[c+3]<<24;return e}}function i(a){var b,g=0,h=a.length,i=new Array(4*h);for(b=0;h>b;b++)i[g++]=c(a[b]),i[g++]=d(a[b]),i[g++]=e(a[b]),i[g++]=f(a[b]);return i}function j(a){var b,g,h,i,j,k,l=new Array(t+1),o=a.length,p=new Array(s),q=new Array(s),r=0;if(16==o)k=10,b=4;else if(24==o)k=12,b=6;else{if(32!=o)throw new Error("Invalid key-length for AES key:"+o);k=14,b=8}for(g=0;t+1>g;g++)l[g]=new Uint32Array(4);for(g=0,h=0;o>h;h++,g+=4)p[h]=a.charCodeAt(g)|a.charCodeAt(g+1)<<8|a.charCodeAt(g+2)<<16|a.charCodeAt(g+3)<<24;for(h=b-1;h>=0;h--)q[h]=p[h];for(i=0,j=0,h=0;b>h&&k+1>i;){for(;b>h&&4>j;h++,j++)l[i][j]=q[h];4==j&&(i++,j=0)}for(;k+1>i;){var u=q[b-1];if(q[0]^=n[d(u)]|n[e(u)]<<8|n[f(u)]<<16|n[c(u)]<<24,q[0]^=m[r++],8!=b)for(h=1;b>h;h++)q[h]^=q[h-1];else{for(h=1;b/2>h;h++)q[h]^=q[h-1];for(u=q[b/2-1],q[b/2]^=n[c(u)]|n[d(u)]<<8|n[e(u)]<<16|n[f(u)]<<24,h=b/2+1;b>h;h++)q[h]^=q[h-1]}for(h=0;b>h&&k+1>i;){for(;b>h&&4>j;h++,j++)l[i][j]=q[h];4==j&&(i++,j=0)}}return{rounds:k,rk:l}}function k(a,b,c){var d,e,f;for(f=h(a),e=b.rounds,d=0;e-1>d;d++)c[0]=f[0]^b.rk[d][0],c[1]=f[1]^b.rk[d][1],c[2]=f[2]^b.rk[d][2],c[3]=f[3]^b.rk[d][3],f[0]=o[255&c[0]]^p[c[1]>>8&255]^q[c[2]>>16&255]^r[c[3]>>>24],f[1]=o[255&c[1]]^p[c[2]>>8&255]^q[c[3]>>16&255]^r[c[0]>>>24],f[2]=o[255&c[2]]^p[c[3]>>8&255]^q[c[0]>>16&255]^r[c[1]>>>24],f[3]=o[255&c[3]]^p[c[0]>>8&255]^q[c[1]>>16&255]^r[c[2]>>>24];return d=e-1,c[0]=f[0]^b.rk[d][0],c[1]=f[1]^b.rk[d][1],c[2]=f[2]^b.rk[d][2],c[3]=f[3]^b.rk[d][3],f[0]=g(c[0],c[1],c[2],c[3])^b.rk[e][0],f[1]=g(c[1],c[2],c[3],c[0])^b.rk[e][1],f[2]=g(c[2],c[3],c[0],c[1])^b.rk[e][2],f[3]=g(c[3],c[0],c[1],c[2])^b.rk[e][3],i(f)}function l(a){var b=function(a){this.key=j(a),this._temp=new Uint32Array(this.blockSize/4),this.encrypt=function(a){return k(a,this.key,this._temp)}};return b.blockSize=b.prototype.blockSize=16,b.keySize=b.prototype.keySize=a/8,b}var m=(a("../../util.js"),new Uint8Array([1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145])),n=new Uint8Array([99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22]),o=new Uint32Array([2774754246,2222750968,2574743534,2373680118,234025727,3177933782,2976870366,1422247313,1345335392,50397442,2842126286,2099981142,436141799,1658312629,3870010189,2591454956,1170918031,2642575903,1086966153,2273148410,368769775,3948501426,3376891790,200339707,3970805057,1742001331,4255294047,3937382213,3214711843,4154762323,2524082916,1539358875,3266819957,486407649,2928907069,1780885068,1513502316,1094664062,49805301,1338821763,1546925160,4104496465,887481809,150073849,2473685474,1943591083,1395732834,1058346282,201589768,1388824469,1696801606,1589887901,672667696,2711000631,251987210,3046808111,151455502,907153956,2608889883,1038279391,652995533,1764173646,3451040383,2675275242,453576978,2659418909,1949051992,773462580,756751158,2993581788,3998898868,4221608027,4132590244,1295727478,1641469623,3467883389,2066295122,1055122397,1898917726,2542044179,4115878822,1758581177,0,753790401,1612718144,536673507,3367088505,3982187446,3194645204,1187761037,3653156455,1262041458,3729410708,3561770136,3898103984,1255133061,1808847035,720367557,3853167183,385612781,3309519750,3612167578,1429418854,2491778321,3477423498,284817897,100794884,2172616702,4031795360,1144798328,3131023141,3819481163,4082192802,4272137053,3225436288,2324664069,2912064063,3164445985,1211644016,83228145,3753688163,3249976951,1977277103,1663115586,806359072,452984805,250868733,1842533055,1288555905,336333848,890442534,804056259,3781124030,2727843637,3427026056,957814574,1472513171,4071073621,2189328124,1195195770,2892260552,3881655738,723065138,2507371494,2690670784,2558624025,3511635870,2145180835,1713513028,2116692564,2878378043,2206763019,3393603212,703524551,3552098411,1007948840,2044649127,3797835452,487262998,1994120109,1004593371,1446130276,1312438900,503974420,3679013266,168166924,1814307912,3831258296,1573044895,1859376061,4021070915,2791465668,2828112185,2761266481,937747667,2339994098,854058965,1137232011,1496790894,3077402074,2358086913,1691735473,3528347292,3769215305,3027004632,4199962284,133494003,636152527,2942657994,2390391540,3920539207,403179536,3585784431,2289596656,1864705354,1915629148,605822008,4054230615,3350508659,1371981463,602466507,2094914977,2624877800,555687742,3712699286,3703422305,2257292045,2240449039,2423288032,1111375484,3300242801,2858837708,3628615824,84083462,32962295,302911004,2741068226,1597322602,4183250862,3501832553,2441512471,1489093017,656219450,3114180135,954327513,335083755,3013122091,856756514,3144247762,1893325225,2307821063,2811532339,3063651117,572399164,2458355477,552200649,1238290055,4283782570,2015897680,2061492133,2408352771,4171342169,2156497161,386731290,3669999461,837215959,3326231172,3093850320,3275833730,2962856233,1999449434,286199582,3417354363,4233385128,3602627437,974525996]),p=new Uint32Array([1667483301,2088564868,2004348569,2071721613,4076011277,1802229437,1869602481,3318059348,808476752,16843267,1734856361,724260477,4278118169,3621238114,2880130534,1987505306,3402272581,2189565853,3385428288,2105408135,4210749205,1499050731,1195871945,4042324747,2913812972,3570709351,2728550397,2947499498,2627478463,2762232823,1920132246,3233848155,3082253762,4261273884,2475900334,640044138,909536346,1061125697,4160222466,3435955023,875849820,2779075060,3857043764,4059166984,1903288979,3638078323,825320019,353708607,67373068,3351745874,589514341,3284376926,404238376,2526427041,84216335,2593796021,117902857,303178806,2155879323,3806519101,3958099238,656887401,2998042573,1970662047,151589403,2206408094,741103732,437924910,454768173,1852759218,1515893998,2694863867,1381147894,993752653,3604395873,3014884814,690573947,3823361342,791633521,2223248279,1397991157,3520182632,0,3991781676,538984544,4244431647,2981198280,1532737261,1785386174,3419114822,3200149465,960066123,1246401758,1280088276,1482207464,3486483786,3503340395,4025468202,2863288293,4227591446,1128498885,1296931543,859006549,2240090516,1162185423,4193904912,33686534,2139094657,1347461360,1010595908,2678007226,2829601763,1364304627,2745392638,1077969088,2408514954,2459058093,2644320700,943222856,4126535940,3166462943,3065411521,3671764853,555827811,269492272,4294960410,4092853518,3537026925,3452797260,202119188,320022069,3974939439,1600110305,2543269282,1145342156,387395129,3301217111,2812761586,2122251394,1027439175,1684326572,1566423783,421081643,1936975509,1616953504,2172721560,1330618065,3705447295,572671078,707417214,2425371563,2290617219,1179028682,4008625961,3099093971,336865340,3739133817,1583267042,185275933,3688607094,3772832571,842163286,976909390,168432670,1229558491,101059594,606357612,1549580516,3267534685,3553869166,2896970735,1650640038,2442213800,2509582756,3840201527,2038035083,3890730290,3368586051,926379609,1835915959,2374828428,3587551588,1313774802,2846444e3,1819072692,1448520954,4109693703,3941256997,1701169839,2054878350,2930657257,134746136,3132780501,2021191816,623200879,774790258,471611428,2795919345,3031724999,3334903633,3907570467,3722289532,1953818780,522141217,1263245021,3183305180,2341145990,2324303749,1886445712,1044282434,3048567236,1718013098,1212715224,50529797,4143380225,235805714,1633796771,892693087,1465364217,3115936208,2256934801,3250690392,488454695,2661164985,3789674808,4177062675,2560109491,286335539,1768542907,3654920560,2391672713,2492740519,2610638262,505297954,2273777042,3924412704,3469641545,1431677695,673730680,3755976058,2357986191,2711706104,2307459456,218962455,3216991706,3873888049,1111655622,1751699640,1094812355,2576951728,757946999,252648977,2964356043,1414834428,3149622742,370551866]),q=new Uint32Array([1673962851,2096661628,2012125559,2079755643,4076801522,1809235307,1876865391,3314635973,811618352,16909057,1741597031,727088427,4276558334,3618988759,2874009259,1995217526,3398387146,2183110018,3381215433,2113570685,4209972730,1504897881,1200539975,4042984432,2906778797,3568527316,2724199842,2940594863,2619588508,2756966308,1927583346,3231407040,3077948087,4259388669,2470293139,642542118,913070646,1065238847,4160029431,3431157708,879254580,2773611685,3855693029,4059629809,1910674289,3635114968,828527409,355090197,67636228,3348452039,591815971,3281870531,405809176,2520228246,84545285,2586817946,118360327,304363026,2149292928,3806281186,3956090603,659450151,2994720178,1978310517,152181513,2199756419,743994412,439627290,456535323,1859957358,1521806938,2690382752,1386542674,997608763,3602342358,3011366579,693271337,3822927587,794718511,2215876484,1403450707,3518589137,0,3988860141,541089824,4242743292,2977548465,1538714971,1792327274,3415033547,3194476990,963791673,1251270218,1285084236,1487988824,3481619151,3501943760,4022676207,2857362858,4226619131,1132905795,1301993293,862344499,2232521861,1166724933,4192801017,33818114,2147385727,1352724560,1014514748,2670049951,2823545768,1369633617,2740846243,1082179648,2399505039,2453646738,2636233885,946882616,4126213365,3160661948,3061301686,3668932058,557998881,270544912,4293204735,4093447923,3535760850,3447803085,202904588,321271059,3972214764,1606345055,2536874647,1149815876,388905239,3297990596,2807427751,2130477694,1031423805,1690872932,1572530013,422718233,1944491379,1623236704,2165938305,1335808335,3701702620,574907938,710180394,2419829648,2282455944,1183631942,4006029806,3094074296,338181140,3735517662,1589437022,185998603,3685578459,3772464096,845436466,980700730,169090570,1234361161,101452294,608726052,1555620956,3265224130,3552407251,2890133420,1657054818,2436475025,2503058581,3839047652,2045938553,3889509095,3364570056,929978679,1843050349,2365688973,3585172693,1318900302,2840191145,1826141292,1454176854,4109567988,3939444202,1707781989,2062847610,2923948462,135272456,3127891386,2029029496,625635109,777810478,473441308,2790781350,3027486644,3331805638,3905627112,3718347997,1961401460,524165407,1268178251,3177307325,2332919435,2316273034,1893765232,1048330814,3044132021,1724688998,1217452104,50726147,4143383030,236720654,1640145761,896163637,1471084887,3110719673,2249691526,3248052417,490350365,2653403550,3789109473,4176155640,2553000856,287453969,1775418217,3651760345,2382858638,2486413204,2603464347,507257374,2266337927,3922272489,3464972750,1437269845,676362280,3752164063,2349043596,2707028129,2299101321,219813645,3211123391,3872862694,1115997762,1758509160,1099088705,2569646233,760903469,253628687,2960903088,1420360788,3144537787,371997206]),r=new Uint32Array([3332727651,4169432188,4003034999,4136467323,4279104242,3602738027,3736170351,2438251973,1615867952,33751297,3467208551,1451043627,3877240574,3043153879,1306962859,3969545846,2403715786,530416258,2302724553,4203183485,4011195130,3001768281,2395555655,4211863792,1106029997,3009926356,1610457762,1173008303,599760028,1408738468,3835064946,2606481600,1975695287,3776773629,1034851219,1282024998,1817851446,2118205247,4110612471,2203045068,1750873140,1374987685,3509904869,4178113009,3801313649,2876496088,1649619249,708777237,135005188,2505230279,1181033251,2640233411,807933976,933336726,168756485,800430746,235472647,607523346,463175808,3745374946,3441880043,1315514151,2144187058,3936318837,303761673,496927619,1484008492,875436570,908925723,3702681198,3035519578,1543217312,2767606354,1984772923,3076642518,2110698419,1383803177,3711886307,1584475951,328696964,2801095507,3110654417,0,3240947181,1080041504,3810524412,2043195825,3069008731,3569248874,2370227147,1742323390,1917532473,2497595978,2564049996,2968016984,2236272591,3144405200,3307925487,1340451498,3977706491,2261074755,2597801293,1716859699,294946181,2328839493,3910203897,67502594,4269899647,2700103760,2017737788,632987551,1273211048,2733855057,1576969123,2160083008,92966799,1068339858,566009245,1883781176,4043634165,1675607228,2009183926,2943736538,1113792801,540020752,3843751935,4245615603,3211645650,2169294285,403966988,641012499,3274697964,3202441055,899848087,2295088196,775493399,2472002756,1441965991,4236410494,2051489085,3366741092,3135724893,841685273,3868554099,3231735904,429425025,2664517455,2743065820,1147544098,1417554474,1001099408,193169544,2362066502,3341414126,1809037496,675025940,2809781982,3168951902,371002123,2910247899,3678134496,1683370546,1951283770,337512970,2463844681,201983494,1215046692,3101973596,2673722050,3178157011,1139780780,3299238498,967348625,832869781,3543655652,4069226873,3576883175,2336475336,1851340599,3669454189,25988493,2976175573,2631028302,1239460265,3635702892,2902087254,4077384948,3475368682,3400492389,4102978170,1206496942,270010376,1876277946,4035475576,1248797989,1550986798,941890588,1475454630,1942467764,2538718918,3408128232,2709315037,3902567540,1042358047,2531085131,1641856445,226921355,260409994,3767562352,2084716094,1908716981,3433719398,2430093384,100991747,4144101110,470945294,3265487201,1784624437,2935576407,1775286713,395413126,2572730817,975641885,666476190,3644383713,3943954680,733190296,573772049,3535497577,2842745305,126455438,866620564,766942107,1008868894,361924487,3374377449,2269761230,2868860245,1350051880,2776293343,59739276,1509466529,159418761,437718285,1708834751,3610371814,2227585602,3501746280,2193834305,699439513,1517759789,504434447,2076946608,2835108948,1842789307,742004246]),s=8,t=14;b.exports={};var u=[128,192,256];for(var v in u)b.exports[u[v]]=l(u[v])},{"../../util.js":61}],7:[function(a,b){function c(){}function d(a){this.bf=new c,this.bf.init(e.str2bin(a)),this.encrypt=function(a){return this.bf.encrypt_block(a)}}c.prototype.BLOCKSIZE=8,c.prototype.SBOXES=[[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946],[1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055],[3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504],[976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462]],c.prototype.PARRAY=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],c.prototype.NN=16,c.prototype._clean=function(a){if(0>a){var b=2147483647&a; +/*! OpenPGPjs.org this is LGPL licensed code, see LICENSE/our website for more information.- v0.6.0 - 2014-05-09 */!function(a){"object"==typeof exports?module.exports=a():"function"==typeof define&&define.amd?define(a):"undefined"!=typeof window?window.openpgp=a():"undefined"!=typeof global?global.openpgp=a():"undefined"!=typeof self&&(self.openpgp=a())}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g>=1,0===I&&(I=b(),a=1&I,I=I>>1|128),a}function e(a){for(var b=0,c=a;c--;)b=b<<1|d();return a&&(b=A[b]>>8-a),b}function f(){y=0}function g(a){r++,x[y++]=a,t.push(String.fromCharCode(a)),32768==y&&(y=0)}function h(){this.b0=0,this.b1=0,this.jump=null,this.jumppos=-1}function i(){for(;;){if(S[R]>=U)return-1;if(T[S[R]]==R)return S[R]++;S[R]++}}function j(){var a,b=Q[P];if(u&&document.write("
len:"+R+" treepos:"+P),17==R)return-1;if(P++,R++,a=i(),u&&document.write("
IsPat "+a),a>=0)b.b0=a,u&&document.write("
b0 "+b.b0);else if(b.b0=32768,u&&document.write("
b0 "+b.b0),j())return-1;if(a=i(),a>=0)b.b1=a,u&&document.write("
b1 "+b.b1),b.jump=null;else if(b.b1=32768,u&&document.write("
b1 "+b.b1),b.jump=Q[P],b.jumppos=P,j())return-1;return R--,0}function k(a,b,c,d){var e;for(u&&document.write("currentTree "+a+" numval "+b+" lengths "+c+" show "+d),Q=a,P=0,T=c,U=b,e=0;17>e;e++)S[e]=0;if(R=0,j())return u&&alert("invalid huffman tree\n"),-1;if(u){document.write("
Tree: "+Q.length);for(var f=0;32>f;f++)document.write("Places["+f+"].b0="+Q[f].b0+"
"),document.write("Places["+f+"].b1="+Q[f].b1+"
")}return 0}function l(a){for(var b,c,e,f=0,g=a[f];;)if(e=d(),u&&document.write("b="+e),e){if(!(32768&g.b1))return u&&document.write("ret1"),g.b1;for(g=g.jump,b=a.length,c=0;b>c;c++)if(a[c]===g){f=c;break}}else{if(!(32768&g.b0))return u&&document.write("ret2"),g.b0;f++,g=a[f]}}function m(){var a,i,j,m,n,o,p;do{switch(a=d(),j=e(2)){case 0:u&&alert("Stored\n");break;case 1:u&&alert("Fixed Huffman codes\n");break;case 2:u&&alert("Dynamic Huffman codes\n");break;case 3:u&&alert("Reserved block type!!\n");break;default:u&&alert("Unexpected value %d!\n",j)}if(0===j){var q,r;for(c(),q=b(),q|=b()<<8,r=b(),r|=b()<<8,65535&(q^~r)&&document.write("BlockLen checksum mismatch\n");q--;)i=b(),g(i)}else if(1==j)for(;;)if(n=A[e(7)]>>1,n>23?(n=n<<1|d(),n>199?(n-=128,n=n<<1|d()):(n-=48,n>143&&(n+=136))):n+=256,256>n)g(n);else{if(256==n)break;for(n-=257,o=e(C[n])+B[n],n=A[e(5)]>>3,E[n]>8?(p=e(8),p|=e(E[n]-8)<<8):p=e(E[n]),p+=D[n],n=0;o>n;n++)i=x[y-p&32767],g(i)}else if(2==j){var s,t,v,w,z=new Array(320);for(t=257+e(5),v=1+e(5),w=4+e(4),n=0;19>n;n++)z[n]=0;for(n=0;w>n;n++)z[F[n]]=e(3);for(o=O.length,m=0;o>m;m++)O[m]=new h;if(k(O,19,z,0))return f(),1;if(u){document.write("
distanceTree");for(var G=0;G"+O[G].b0+" "+O[G].b1+" "+O[G].jump+" "+O[G].jumppos)}s=t+v,m=0;var H=-1;for(u&&document.write("
n="+s+" bits: "+J+"
");s>m;)if(H++,n=l(O),u&&document.write("
"+H+" i:"+m+" decode: "+n+" bits "+J+"
"),16>n)z[m++]=n;else if(16==n){var I;if(n=3+e(2),m+n>s)return f(),1;for(I=m?z[m-1]:0;n--;)z[m++]=I}else{if(n=17==n?3+e(3):11+e(7),m+n>s)return f(),1;for(;n--;)z[m++]=0}for(o=N.length,m=0;o>m;m++)N[m]=new h;if(k(N,t,z,0))return f(),1;for(o=N.length,m=0;o>m;m++)O[m]=new h;var K=[];for(m=t;mliteralTree");a:for(;;)if(n=l(N),n>=256){if(n-=256,0===n)break;for(n--,o=e(C[n])+B[n],n=l(O),E[n]>8?(p=e(8),p|=e(E[n]-8)<<8):p=e(E[n]),p+=D[n];o--;){if(0>y-p)break a;i=x[y-p&32767],g(i)}}else g(n)}}while(!a);return f(),c(),0}function n(){u&&alert("NEXTFILE"),t=[];var a=[];if(z=!1,a[0]=b(),a[1]=b(),u&&alert("type: "+a[0]+" "+a[1]),a[0]==parseInt("78",16)&&a[1]==parseInt("da",16)&&(u&&alert("GEONExT-GZIP"),m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="geonext.gxt",v++),a[0]==parseInt("78",16)&&a[1]==parseInt("9c",16)&&(u&&alert("ZLIB"),m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="ZLIB",v++),a[0]==parseInt("1f",16)&&a[1]==parseInt("8b",16)&&(u&&alert("GZIP"),o(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]="file",v++),a[0]==parseInt("50",16)&&a[1]==parseInt("4b",16)&&(z=!0,a[2]=b(),a[3]=b(),a[2]==parseInt("3",16)&&a[3]==parseInt("4",16))){a[0]=b(),a[1]=b(),u&&alert("ZIP-Version: "+a[1]+" "+a[0]/10+"."+a[0]%10),p=b(),p|=b()<<8,u&&alert("gpflags: "+p);var c=b();c|=b()<<8,u&&alert("method: "+c),b(),b(),b(),b();var d=b();d|=b()<<8,d|=b()<<16,d|=b()<<24;var e=b();e|=b()<<8,e|=b()<<16,e|=b()<<24;var f=b();f|=b()<<8,f|=b()<<16,f|=b()<<24,u&&alert("local CRC: "+d+"\nlocal Size: "+f+"\nlocal CompSize: "+e);var g=b();g|=b()<<8;var h=b();h|=b()<<8,u&&alert("filelen "+g),j=0,L=[];for(var i;g--;)i=b(),"/"==i|":"==i?j=0:K-1>j&&(L[j++]=String.fromCharCode(i));u&&alert("nameBuf: "+L),s||(s=L);for(var j=0;h>j;)i=b(),j++;q=4294967295,r=0,0===f&&"/"==fileOut.charAt(s.length-1)&&u&&alert("skipdir"),8==c&&(m(),u&&alert(t.join("")),w[v]=new Array(2),w[v][0]=t.join(""),w[v][1]=L.join(""),v++),o()}}function o(){var a,c,d,e,f,g,h=[];if(8&p&&(h[0]=b(),h[1]=b(),h[2]=b(),h[3]=b(),h[0]==parseInt("50",16)&&h[1]==parseInt("4b",16)&&h[2]==parseInt("07",16)&&h[3]==parseInt("08",16)?(a=b(),a|=b()<<8,a|=b()<<16,a|=b()<<24):a=h[0]|h[1]<<8|h[2]<<16|h[3]<<24,c=b(),c|=b()<<8,c|=b()<<16,c|=b()<<24,d=b(),d|=b()<<8,d|=b()<<16,d|=b()<<24,u&&alert("CRC:")),z&&n(),h[0]=b(),8!=h[0])return u&&alert("Unknown compression method!"),0;if(p=b(),u&&p&~parseInt("1f",16)&&alert("Unknown flags set!"),b(),b(),b(),b(),b(),e=b(),4&p)for(h[0]=b(),h[2]=b(),R=h[0]+256*h[1],u&&alert("Extra field size: "+R),f=0;R>f;f++)b();if(8&p){for(f=0,L=[];g=b();)("7"==g||":"==g)&&(f=0),K-1>f&&(L[f++]=g);u&&alert("original file name: "+L)}if(16&p)for(;g=b(););2&p&&(b(),b()),m(),a=b(),a|=b()<<8,a|=b()<<16,a|=b()<<24,d=b(),d|=b()<<8,d|=b()<<16,d|=b()<<24,z&&n()}var p,q,r,s,t=[],u=!1,v=0,w=[],x=new Array(32768),y=0,z=!1,A=[0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248,4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251,7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255],B=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],C=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],D=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],E=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],F=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],G=a,H=0,I=1,J=0,K=256,L=[],M=288,N=new Array(M),O=new Array(32),P=0,Q=null,R=(new Array(64),new Array(64),0),S=new Array(17);S[0]=0;var T,U;JXG.Util.Unzip.prototype.unzipFile=function(a){var b;for(this.unzip(),b=0;b>2,f=(3&b)<<4|c>>4,g=(15&c)<<2|d>>6,h=63&d,isNaN(c)?g=h=64:isNaN(d)&&(h=64),i.push([this._keyStr.charAt(e),this._keyStr.charAt(f),this._keyStr.charAt(g),this._keyStr.charAt(h)].join(""));return i.join("")},decode:function(a,b){var c,d,e,f,g,h,i,j=[],k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,j.push(String.fromCharCode(c)),64!=h&&j.push(String.fromCharCode(d)),64!=i&&j.push(String.fromCharCode(e));return j=j.join(""),b&&(j=JXG.Util.Base64._utf8_decode(j)),j},_utf8_encode:function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;cd?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(d>>6|192),b+=String.fromCharCode(63&d|128)):(b+=String.fromCharCode(d>>12|224),b+=String.fromCharCode(d>>6&63|128),b+=String.fromCharCode(63&d|128))}return b},_utf8_decode:function(a){for(var b=[],c=0,d=0,e=0,f=0;cd?(b.push(String.fromCharCode(d)),c++):d>191&&224>d?(e=a.charCodeAt(c+1),b.push(String.fromCharCode((31&d)<<6|63&e)),c+=2):(e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b.push(String.fromCharCode((15&d)<<12|(63&e)<<6|63&f)),c+=3);return b.join("")},_destrip:function(a,b){var c,d,e=[],f=[];for(null===b&&(b=76),a.replace(/ /g,""),c=a.length/b,d=0;c>d;d++)e[d]=a.substr(d*b,b);for(c!=a.length/b&&(e[e.length]=a.substr(c*b,a.length-c*b)),d=0;d255)switch(c){case 8364:c=128;break;case 8218:c=130;break;case 402:c=131;break;case 8222:c=132;break;case 8230:c=133;break;case 8224:c=134;break;case 8225:c=135;break;case 710:c=136;break;case 8240:c=137;break;case 352:c=138;break;case 8249:c=139;break;case 338:c=140;break;case 381:c=142;break;case 8216:c=145;break;case 8217:c=146;break;case 8220:c=147;break;case 8221:c=148;break;case 8226:c=149;break;case 8211:c=150;break;case 8212:c=151;break;case 732:c=152;break;case 8482:c=153;break;case 353:c=154;break;case 8250:c=155;break;case 339:c=156;break;case 382:c=158;break;case 376:c=159}return c},JXG.Util.utf8Decode=function(a){var b,c=[],d=0,e=0,f=0;if(!JXG.exists(a))return"";for(;de?(c.push(String.fromCharCode(e)),d++):e>191&&224>e?(f=a.charCodeAt(d+1),c.push(String.fromCharCode((31&e)<<6|63&f)),d+=2):(f=a.charCodeAt(d+1),b=a.charCodeAt(d+2),c.push(String.fromCharCode((15&e)<<12|(63&f)<<6|63&b)),d+=3);return c.join("")},JXG.Util.genUUID=function(){for(var a,b="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),c=new Array(36),d=0,e=0;36>e;e++)8==e||13==e||18==e||23==e?c[e]="-":14==e?c[e]="4":(2>=d&&(d=33554432+16777216*Math.random()|0),a=15&d,d>>=4,c[e]=b[19==e?3&a|8:a]);return c.join("")},b.exports=JXG},{}],3:[function(a,b){var c=a("../enums.js");b.exports={prefer_hash_algorithm:c.hash.sha256,encryption_cipher:c.symmetric.aes256,compression:c.compression.zip,integrity_protect:!0,rsa_blinding:!0,show_version:!0,show_comment:!0,versionstring:"OpenPGP.js v0.6.0",commentstring:"http://openpgpjs.org",keyserver:"keyserver.linux.it",node_store:"./openpgp.store",debug:!1}},{"../enums.js":30}],4:[function(a,b){b.exports=a("./config.js")},{"./config.js":3}],5:[function(a,b){"use strict";var c=a("../util.js"),d=a("./cipher");b.exports={encrypt:function(a,b,e,f,g){b=new d[b](f);var h=b.blockSize,i=new Uint8Array(h),j=new Uint8Array(h);a=a+a.charAt(h-2)+a.charAt(h-1);var k,l,m,n=new Uint8Array(e.length+2+2*h),o=g?0:2;for(k=0;h>k;k++)i[k]=0;for(j=b.encrypt(i),k=0;h>k;k++)n[k]=j[k]^a.charCodeAt(k);for(i.set(n.subarray(0,h)),j=b.encrypt(i),n[h]=j[0]^a.charCodeAt(h),n[h+1]=j[1]^a.charCodeAt(h+1),i.set(g?n.subarray(2,h+2):n.subarray(0,h)),j=b.encrypt(i),k=0;h>k;k++)n[h+2+k]=j[k+o]^e.charCodeAt(k);for(l=h;lk;k++)n[h+m+k]=j[k]^e.charCodeAt(l+k-o);return n=n.subarray(0,e.length+2+h),c.Uint8Array2str(n)},mdc:function(a,b,e){a=new d[a](b);var f,g=a.blockSize,h=new Uint8Array(g),i=new Uint8Array(g);for(f=0;g>f;f++)h[f]=0;for(h=a.encrypt(h),f=0;g>f;f++)i[f]=e.charCodeAt(f),h[f]^=i[f];return i=a.encrypt(i),c.bin2str(h)+String.fromCharCode(i[0]^e.charCodeAt(g))+String.fromCharCode(i[1]^e.charCodeAt(g+1))},decrypt:function(a,b,c,e){a=new d[a](b);var f,g=a.blockSize,h=new Uint8Array(g),i=new Uint8Array(g),j="",k="";for(f=0;g>f;f++)h[f]=0;for(h=a.encrypt(h),f=0;g>f;f++)i[f]=c.charCodeAt(f),h[f]^=i[f];if(i=a.encrypt(i),h[g-2]!=(i[0]^c.charCodeAt(g))||h[g-1]!=(i[1]^c.charCodeAt(g+1)))throw new Error("CFB decrypt: invalid key");if(e){for(f=0;g>f;f++)h[f]=c.charCodeAt(f+2);for(j=g+2;jf&&f+jf;f++)h[f]=c.charCodeAt(f);for(j=g;jf&&f+jg*j;){var m=a.encrypt(c.str2bin(i));h=e.substring(j*g,j*g+g);for(var n=0;ng;g++)i+=String.fromCharCode(0);else i=f.substring(0,h);for(;e.length>h*j;){var m=a.encrypt(c.str2bin(i));for(i=e.substring(j*h+l,j*h+h+l),g=0;g>8&255}function e(a){return a>>16&255}function f(a){return a>>24&255}function g(a,b,c,e){return d(o[255&a])|d(o[b>>8&255])<<8|d(o[c>>16&255])<<16|d(o[e>>>24])<<24}function h(a){var b,c,d=a.length,e=new Array(d/4);if(a&&!(d%4)){for(b=0,c=0;d>c;c+=4)e[b++]=a[c]|a[c+1]<<8|a[c+2]<<16|a[c+3]<<24;return e}}function i(a){var b,g=0,h=a.length,i=new Array(4*h);for(b=0;h>b;b++)i[g++]=c(a[b]),i[g++]=d(a[b]),i[g++]=e(a[b]),i[g++]=f(a[b]);return i}function j(a){var b,g,h,i,j,k,l=new Array(t+1),o=a.length,p=new Array(s),q=new Array(s),r=0;if(16==o)k=10,b=4;else if(24==o)k=12,b=6;else{if(32!=o)throw new Error("Invalid key-length for AES key:"+o);k=14,b=8}for(g=0;t+1>g;g++)l[g]=new Uint32Array(4);for(g=0,h=0;o>h;h++,g+=4)p[h]=a.charCodeAt(g)|a.charCodeAt(g+1)<<8|a.charCodeAt(g+2)<<16|a.charCodeAt(g+3)<<24;for(h=b-1;h>=0;h--)q[h]=p[h];for(i=0,j=0,h=0;b>h&&k+1>i;){for(;b>h&&4>j;h++,j++)l[i][j]=q[h];4==j&&(i++,j=0)}for(;k+1>i;){var u=q[b-1];if(q[0]^=n[d(u)]|n[e(u)]<<8|n[f(u)]<<16|n[c(u)]<<24,q[0]^=m[r++],8!=b)for(h=1;b>h;h++)q[h]^=q[h-1];else{for(h=1;b/2>h;h++)q[h]^=q[h-1];for(u=q[b/2-1],q[b/2]^=n[c(u)]|n[d(u)]<<8|n[e(u)]<<16|n[f(u)]<<24,h=b/2+1;b>h;h++)q[h]^=q[h-1]}for(h=0;b>h&&k+1>i;){for(;b>h&&4>j;h++,j++)l[i][j]=q[h];4==j&&(i++,j=0)}}return{rounds:k,rk:l}}function k(a,b,c){var d,e,f;for(f=h(a),e=b.rounds,d=0;e-1>d;d++)c[0]=f[0]^b.rk[d][0],c[1]=f[1]^b.rk[d][1],c[2]=f[2]^b.rk[d][2],c[3]=f[3]^b.rk[d][3],f[0]=o[255&c[0]]^p[c[1]>>8&255]^q[c[2]>>16&255]^r[c[3]>>>24],f[1]=o[255&c[1]]^p[c[2]>>8&255]^q[c[3]>>16&255]^r[c[0]>>>24],f[2]=o[255&c[2]]^p[c[3]>>8&255]^q[c[0]>>16&255]^r[c[1]>>>24],f[3]=o[255&c[3]]^p[c[0]>>8&255]^q[c[1]>>16&255]^r[c[2]>>>24];return d=e-1,c[0]=f[0]^b.rk[d][0],c[1]=f[1]^b.rk[d][1],c[2]=f[2]^b.rk[d][2],c[3]=f[3]^b.rk[d][3],f[0]=g(c[0],c[1],c[2],c[3])^b.rk[e][0],f[1]=g(c[1],c[2],c[3],c[0])^b.rk[e][1],f[2]=g(c[2],c[3],c[0],c[1])^b.rk[e][2],f[3]=g(c[3],c[0],c[1],c[2])^b.rk[e][3],i(f)}function l(a){var b=function(a){this.key=j(a),this._temp=new Uint32Array(this.blockSize/4),this.encrypt=function(a){return k(a,this.key,this._temp)}};return b.blockSize=b.prototype.blockSize=16,b.keySize=b.prototype.keySize=a/8,b}var m=(a("../../util.js"),new Uint8Array([1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145])),n=new Uint8Array([99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22]),o=new Uint32Array([2774754246,2222750968,2574743534,2373680118,234025727,3177933782,2976870366,1422247313,1345335392,50397442,2842126286,2099981142,436141799,1658312629,3870010189,2591454956,1170918031,2642575903,1086966153,2273148410,368769775,3948501426,3376891790,200339707,3970805057,1742001331,4255294047,3937382213,3214711843,4154762323,2524082916,1539358875,3266819957,486407649,2928907069,1780885068,1513502316,1094664062,49805301,1338821763,1546925160,4104496465,887481809,150073849,2473685474,1943591083,1395732834,1058346282,201589768,1388824469,1696801606,1589887901,672667696,2711000631,251987210,3046808111,151455502,907153956,2608889883,1038279391,652995533,1764173646,3451040383,2675275242,453576978,2659418909,1949051992,773462580,756751158,2993581788,3998898868,4221608027,4132590244,1295727478,1641469623,3467883389,2066295122,1055122397,1898917726,2542044179,4115878822,1758581177,0,753790401,1612718144,536673507,3367088505,3982187446,3194645204,1187761037,3653156455,1262041458,3729410708,3561770136,3898103984,1255133061,1808847035,720367557,3853167183,385612781,3309519750,3612167578,1429418854,2491778321,3477423498,284817897,100794884,2172616702,4031795360,1144798328,3131023141,3819481163,4082192802,4272137053,3225436288,2324664069,2912064063,3164445985,1211644016,83228145,3753688163,3249976951,1977277103,1663115586,806359072,452984805,250868733,1842533055,1288555905,336333848,890442534,804056259,3781124030,2727843637,3427026056,957814574,1472513171,4071073621,2189328124,1195195770,2892260552,3881655738,723065138,2507371494,2690670784,2558624025,3511635870,2145180835,1713513028,2116692564,2878378043,2206763019,3393603212,703524551,3552098411,1007948840,2044649127,3797835452,487262998,1994120109,1004593371,1446130276,1312438900,503974420,3679013266,168166924,1814307912,3831258296,1573044895,1859376061,4021070915,2791465668,2828112185,2761266481,937747667,2339994098,854058965,1137232011,1496790894,3077402074,2358086913,1691735473,3528347292,3769215305,3027004632,4199962284,133494003,636152527,2942657994,2390391540,3920539207,403179536,3585784431,2289596656,1864705354,1915629148,605822008,4054230615,3350508659,1371981463,602466507,2094914977,2624877800,555687742,3712699286,3703422305,2257292045,2240449039,2423288032,1111375484,3300242801,2858837708,3628615824,84083462,32962295,302911004,2741068226,1597322602,4183250862,3501832553,2441512471,1489093017,656219450,3114180135,954327513,335083755,3013122091,856756514,3144247762,1893325225,2307821063,2811532339,3063651117,572399164,2458355477,552200649,1238290055,4283782570,2015897680,2061492133,2408352771,4171342169,2156497161,386731290,3669999461,837215959,3326231172,3093850320,3275833730,2962856233,1999449434,286199582,3417354363,4233385128,3602627437,974525996]),p=new Uint32Array([1667483301,2088564868,2004348569,2071721613,4076011277,1802229437,1869602481,3318059348,808476752,16843267,1734856361,724260477,4278118169,3621238114,2880130534,1987505306,3402272581,2189565853,3385428288,2105408135,4210749205,1499050731,1195871945,4042324747,2913812972,3570709351,2728550397,2947499498,2627478463,2762232823,1920132246,3233848155,3082253762,4261273884,2475900334,640044138,909536346,1061125697,4160222466,3435955023,875849820,2779075060,3857043764,4059166984,1903288979,3638078323,825320019,353708607,67373068,3351745874,589514341,3284376926,404238376,2526427041,84216335,2593796021,117902857,303178806,2155879323,3806519101,3958099238,656887401,2998042573,1970662047,151589403,2206408094,741103732,437924910,454768173,1852759218,1515893998,2694863867,1381147894,993752653,3604395873,3014884814,690573947,3823361342,791633521,2223248279,1397991157,3520182632,0,3991781676,538984544,4244431647,2981198280,1532737261,1785386174,3419114822,3200149465,960066123,1246401758,1280088276,1482207464,3486483786,3503340395,4025468202,2863288293,4227591446,1128498885,1296931543,859006549,2240090516,1162185423,4193904912,33686534,2139094657,1347461360,1010595908,2678007226,2829601763,1364304627,2745392638,1077969088,2408514954,2459058093,2644320700,943222856,4126535940,3166462943,3065411521,3671764853,555827811,269492272,4294960410,4092853518,3537026925,3452797260,202119188,320022069,3974939439,1600110305,2543269282,1145342156,387395129,3301217111,2812761586,2122251394,1027439175,1684326572,1566423783,421081643,1936975509,1616953504,2172721560,1330618065,3705447295,572671078,707417214,2425371563,2290617219,1179028682,4008625961,3099093971,336865340,3739133817,1583267042,185275933,3688607094,3772832571,842163286,976909390,168432670,1229558491,101059594,606357612,1549580516,3267534685,3553869166,2896970735,1650640038,2442213800,2509582756,3840201527,2038035083,3890730290,3368586051,926379609,1835915959,2374828428,3587551588,1313774802,2846444e3,1819072692,1448520954,4109693703,3941256997,1701169839,2054878350,2930657257,134746136,3132780501,2021191816,623200879,774790258,471611428,2795919345,3031724999,3334903633,3907570467,3722289532,1953818780,522141217,1263245021,3183305180,2341145990,2324303749,1886445712,1044282434,3048567236,1718013098,1212715224,50529797,4143380225,235805714,1633796771,892693087,1465364217,3115936208,2256934801,3250690392,488454695,2661164985,3789674808,4177062675,2560109491,286335539,1768542907,3654920560,2391672713,2492740519,2610638262,505297954,2273777042,3924412704,3469641545,1431677695,673730680,3755976058,2357986191,2711706104,2307459456,218962455,3216991706,3873888049,1111655622,1751699640,1094812355,2576951728,757946999,252648977,2964356043,1414834428,3149622742,370551866]),q=new Uint32Array([1673962851,2096661628,2012125559,2079755643,4076801522,1809235307,1876865391,3314635973,811618352,16909057,1741597031,727088427,4276558334,3618988759,2874009259,1995217526,3398387146,2183110018,3381215433,2113570685,4209972730,1504897881,1200539975,4042984432,2906778797,3568527316,2724199842,2940594863,2619588508,2756966308,1927583346,3231407040,3077948087,4259388669,2470293139,642542118,913070646,1065238847,4160029431,3431157708,879254580,2773611685,3855693029,4059629809,1910674289,3635114968,828527409,355090197,67636228,3348452039,591815971,3281870531,405809176,2520228246,84545285,2586817946,118360327,304363026,2149292928,3806281186,3956090603,659450151,2994720178,1978310517,152181513,2199756419,743994412,439627290,456535323,1859957358,1521806938,2690382752,1386542674,997608763,3602342358,3011366579,693271337,3822927587,794718511,2215876484,1403450707,3518589137,0,3988860141,541089824,4242743292,2977548465,1538714971,1792327274,3415033547,3194476990,963791673,1251270218,1285084236,1487988824,3481619151,3501943760,4022676207,2857362858,4226619131,1132905795,1301993293,862344499,2232521861,1166724933,4192801017,33818114,2147385727,1352724560,1014514748,2670049951,2823545768,1369633617,2740846243,1082179648,2399505039,2453646738,2636233885,946882616,4126213365,3160661948,3061301686,3668932058,557998881,270544912,4293204735,4093447923,3535760850,3447803085,202904588,321271059,3972214764,1606345055,2536874647,1149815876,388905239,3297990596,2807427751,2130477694,1031423805,1690872932,1572530013,422718233,1944491379,1623236704,2165938305,1335808335,3701702620,574907938,710180394,2419829648,2282455944,1183631942,4006029806,3094074296,338181140,3735517662,1589437022,185998603,3685578459,3772464096,845436466,980700730,169090570,1234361161,101452294,608726052,1555620956,3265224130,3552407251,2890133420,1657054818,2436475025,2503058581,3839047652,2045938553,3889509095,3364570056,929978679,1843050349,2365688973,3585172693,1318900302,2840191145,1826141292,1454176854,4109567988,3939444202,1707781989,2062847610,2923948462,135272456,3127891386,2029029496,625635109,777810478,473441308,2790781350,3027486644,3331805638,3905627112,3718347997,1961401460,524165407,1268178251,3177307325,2332919435,2316273034,1893765232,1048330814,3044132021,1724688998,1217452104,50726147,4143383030,236720654,1640145761,896163637,1471084887,3110719673,2249691526,3248052417,490350365,2653403550,3789109473,4176155640,2553000856,287453969,1775418217,3651760345,2382858638,2486413204,2603464347,507257374,2266337927,3922272489,3464972750,1437269845,676362280,3752164063,2349043596,2707028129,2299101321,219813645,3211123391,3872862694,1115997762,1758509160,1099088705,2569646233,760903469,253628687,2960903088,1420360788,3144537787,371997206]),r=new Uint32Array([3332727651,4169432188,4003034999,4136467323,4279104242,3602738027,3736170351,2438251973,1615867952,33751297,3467208551,1451043627,3877240574,3043153879,1306962859,3969545846,2403715786,530416258,2302724553,4203183485,4011195130,3001768281,2395555655,4211863792,1106029997,3009926356,1610457762,1173008303,599760028,1408738468,3835064946,2606481600,1975695287,3776773629,1034851219,1282024998,1817851446,2118205247,4110612471,2203045068,1750873140,1374987685,3509904869,4178113009,3801313649,2876496088,1649619249,708777237,135005188,2505230279,1181033251,2640233411,807933976,933336726,168756485,800430746,235472647,607523346,463175808,3745374946,3441880043,1315514151,2144187058,3936318837,303761673,496927619,1484008492,875436570,908925723,3702681198,3035519578,1543217312,2767606354,1984772923,3076642518,2110698419,1383803177,3711886307,1584475951,328696964,2801095507,3110654417,0,3240947181,1080041504,3810524412,2043195825,3069008731,3569248874,2370227147,1742323390,1917532473,2497595978,2564049996,2968016984,2236272591,3144405200,3307925487,1340451498,3977706491,2261074755,2597801293,1716859699,294946181,2328839493,3910203897,67502594,4269899647,2700103760,2017737788,632987551,1273211048,2733855057,1576969123,2160083008,92966799,1068339858,566009245,1883781176,4043634165,1675607228,2009183926,2943736538,1113792801,540020752,3843751935,4245615603,3211645650,2169294285,403966988,641012499,3274697964,3202441055,899848087,2295088196,775493399,2472002756,1441965991,4236410494,2051489085,3366741092,3135724893,841685273,3868554099,3231735904,429425025,2664517455,2743065820,1147544098,1417554474,1001099408,193169544,2362066502,3341414126,1809037496,675025940,2809781982,3168951902,371002123,2910247899,3678134496,1683370546,1951283770,337512970,2463844681,201983494,1215046692,3101973596,2673722050,3178157011,1139780780,3299238498,967348625,832869781,3543655652,4069226873,3576883175,2336475336,1851340599,3669454189,25988493,2976175573,2631028302,1239460265,3635702892,2902087254,4077384948,3475368682,3400492389,4102978170,1206496942,270010376,1876277946,4035475576,1248797989,1550986798,941890588,1475454630,1942467764,2538718918,3408128232,2709315037,3902567540,1042358047,2531085131,1641856445,226921355,260409994,3767562352,2084716094,1908716981,3433719398,2430093384,100991747,4144101110,470945294,3265487201,1784624437,2935576407,1775286713,395413126,2572730817,975641885,666476190,3644383713,3943954680,733190296,573772049,3535497577,2842745305,126455438,866620564,766942107,1008868894,361924487,3374377449,2269761230,2868860245,1350051880,2776293343,59739276,1509466529,159418761,437718285,1708834751,3610371814,2227585602,3501746280,2193834305,699439513,1517759789,504434447,2076946608,2835108948,1842789307,742004246]),s=8,t=14;b.exports={};var u=[128,192,256];for(var v in u)b.exports[u[v]]=l(u[v])},{"../../util.js":61}],7:[function(a,b){function c(){}function d(a){this.bf=new c,this.bf.init(e.str2bin(a)),this.encrypt=function(a){return this.bf.encrypt_block(a)}}c.prototype.BLOCKSIZE=8,c.prototype.SBOXES=[[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946],[1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055],[3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504],[976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462]],c.prototype.PARRAY=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],c.prototype.NN=16,c.prototype._clean=function(a){if(0>a){var b=2147483647&a; a=b+2147483648}return a},c.prototype._F=function(a){var b,c,d,e,f;return e=255&a,a>>>=8,d=255&a,a>>>=8,c=255&a,a>>>=8,b=255&a,f=this.sboxes[0][b]+this.sboxes[1][c],f^=this.sboxes[2][d],f+=this.sboxes[3][e]},c.prototype._encrypt_block=function(a){var b,c=a[0],d=a[1];for(b=0;b>>24-8*b&255,e[b+d]=c[1]>>>24-8*b&255;return e},c.prototype._decrypt_block=function(a){var b,c=a[0],d=a[1];for(b=this.NN+1;b>1;--b){c^=this.parray[b],d=this._F(c)^d;var e=c;c=d,d=e}c^=this.parray[1],d^=this.parray[0],a[0]=this._clean(d),a[1]=this._clean(c)},c.prototype.init=function(a){var b,c=0;for(this.parray=[],b=0;bd;++d)e=e<<8|255&a[c],++c>=a.length&&(c=0);this.parray[b]=this.PARRAY[b]^e}for(this.sboxes=[],b=0;4>b;++b)for(this.sboxes[b]=[],c=0;256>c;++c)this.sboxes[b][c]=this.SBOXES[b][c];var f=[0,0];for(b=0;bb;++b)for(c=0;256>c;c+=2)this._encrypt_block(f),this.sboxes[b][c+0]=f[0],this.sboxes[b][c+1]=f[1]};var e=a("../../util.js");b.exports=d,b.exports.keySize=d.prototype.keySize=16,b.exports.blockSize=d.prototype.blockSize=16},{"../../util.js":61}],8:[function(a,b){function c(){function a(a,b,c){var d=b+a,e=d<>>32-c;return(f[0][e>>>24]^f[1][e>>>16&255])-f[2][e>>>8&255]+f[3][255&e]}function b(a,b,c){var d=b^a,e=d<>>32-c;return f[0][e>>>24]-f[1][e>>>16&255]+f[2][e>>>8&255]^f[3][255&e]}function c(a,b,c){var d=b-a,e=d<>>32-c;return(f[0][e>>>24]+f[1][e>>>16&255]^f[2][e>>>8&255])-f[3][255&e]}this.BlockSize=8,this.KeySize=16,this.setKey=function(a){if(this.masking=new Array(16),this.rotate=new Array(16),this.reset(),a.length!=this.KeySize)throw new Error("CAST-128: keys must be 16 bytes");return this.keySchedule(a),!0},this.reset=function(){for(var a=0;16>a;a++)this.masking[a]=0,this.rotate[a]=0},this.getBlockSize=function(){return BlockSize},this.encrypt=function(d){for(var e=new Array(d.length),f=0;f>>24&255,e[f+1]=i>>>16&255,e[f+2]=i>>>8&255,e[f+3]=255&i,e[f+4]=h>>>24&255,e[f+5]=h>>>16&255,e[f+6]=h>>>8&255,e[f+7]=255&h}return e},this.decrypt=function(d){for(var e=new Array(d.length),f=0;f>>24&255,e[f+1]=i>>>16&255,e[f+2]=i>>>8&255,e[f+3]=255&i,e[f+4]=h>>>24&255,e[f+5]=h>>16&255,e[f+6]=h>>8&255,e[f+7]=255&h}return e};var d=new Array(4);d[0]=new Array(4),d[0][0]=new Array(4,0,13,15,12,14,8),d[0][1]=new Array(5,2,16,18,17,19,10),d[0][2]=new Array(6,3,23,22,21,20,9),d[0][3]=new Array(7,1,26,25,27,24,11),d[1]=new Array(4),d[1][0]=new Array(0,6,21,23,20,22,16),d[1][1]=new Array(1,4,0,2,1,3,18),d[1][2]=new Array(2,5,7,6,5,4,17),d[1][3]=new Array(3,7,10,9,11,8,19),d[2]=new Array(4),d[2][0]=new Array(4,0,13,15,12,14,8),d[2][1]=new Array(5,2,16,18,17,19,10),d[2][2]=new Array(6,3,23,22,21,20,9),d[2][3]=new Array(7,1,26,25,27,24,11),d[3]=new Array(4),d[3][0]=new Array(0,6,21,23,20,22,16),d[3][1]=new Array(1,4,0,2,1,3,18),d[3][2]=new Array(2,5,7,6,5,4,17),d[3][3]=new Array(3,7,10,9,11,8,19);var e=new Array(4);e[0]=new Array(4),e[0][0]=new Array(24,25,23,22,18),e[0][1]=new Array(26,27,21,20,22),e[0][2]=new Array(28,29,19,18,25),e[0][3]=new Array(30,31,17,16,28),e[1]=new Array(4),e[1][0]=new Array(3,2,12,13,8),e[1][1]=new Array(1,0,14,15,13),e[1][2]=new Array(7,6,8,9,3),e[1][3]=new Array(5,4,10,11,7),e[2]=new Array(4),e[2][0]=new Array(19,18,28,29,25),e[2][1]=new Array(17,16,30,31,28),e[2][2]=new Array(23,22,24,25,18),e[2][3]=new Array(21,20,26,27,22),e[3]=new Array(4),e[3][0]=new Array(8,9,7,6,3),e[3][1]=new Array(10,11,5,4,7),e[3][2]=new Array(12,13,3,2,8),e[3][3]=new Array(14,15,1,0,13),this.keySchedule=function(a){var b,c,g=new Array(8),h=new Array(32);for(b=0;4>b;b++)c=4*b,g[b]=a[c]<<24|a[c+1]<<16|a[c+2]<<8|a[c+3];for(var i,j=[6,7,4,5],k=0,l=0;2>l;l++)for(var m=0;4>m;m++){for(c=0;4>c;c++){var n=d[m][c];i=g[n[1]],i^=f[4][g[n[2]>>>2]>>>24-8*(3&n[2])&255],i^=f[5][g[n[3]>>>2]>>>24-8*(3&n[3])&255],i^=f[6][g[n[4]>>>2]>>>24-8*(3&n[4])&255],i^=f[7][g[n[5]>>>2]>>>24-8*(3&n[5])&255],i^=f[j[c]][g[n[6]>>>2]>>>24-8*(3&n[6])&255],g[n[0]]=i}for(c=0;4>c;c++){var o=e[m][c];i=f[4][g[o[0]>>>2]>>>24-8*(3&o[0])&255],i^=f[5][g[o[1]>>>2]>>>24-8*(3&o[1])&255],i^=f[6][g[o[2]>>>2]>>>24-8*(3&o[2])&255],i^=f[7][g[o[3]>>>2]>>>24-8*(3&o[3])&255],i^=f[4+c][g[o[4]>>>2]>>>24-8*(3&o[4])&255],h[k]=i,k++}}for(b=0;16>b;b++)this.masking[b]=h[b],this.rotate[b]=31&h[16+b]};var f=new Array(8);f[0]=new Array(821772500,2678128395,1810681135,1059425402,505495343,2617265619,1610868032,3483355465,3218386727,2294005173,3791863952,2563806837,1852023008,365126098,3269944861,584384398,677919599,3229601881,4280515016,2002735330,1136869587,3744433750,2289869850,2731719981,2714362070,879511577,1639411079,575934255,717107937,2857637483,576097850,2731753936,1725645e3,2810460463,5111599,767152862,2543075244,1251459544,1383482551,3052681127,3089939183,3612463449,1878520045,1510570527,2189125840,2431448366,582008916,3163445557,1265446783,1354458274,3529918736,3202711853,3073581712,3912963487,3029263377,1275016285,4249207360,2905708351,3304509486,1442611557,3585198765,2712415662,2731849581,3248163920,2283946226,208555832,2766454743,1331405426,1447828783,3315356441,3108627284,2957404670,2981538698,3339933917,1669711173,286233437,1465092821,1782121619,3862771680,710211251,980974943,1651941557,430374111,2051154026,704238805,4128970897,3144820574,2857402727,948965521,3333752299,2227686284,718756367,2269778983,2731643755,718440111,2857816721,3616097120,1113355533,2478022182,410092745,1811985197,1944238868,2696854588,1415722873,1682284203,1060277122,1998114690,1503841958,82706478,2315155686,1068173648,845149890,2167947013,1768146376,1993038550,3566826697,3390574031,940016341,3355073782,2328040721,904371731,1205506512,4094660742,2816623006,825647681,85914773,2857843460,1249926541,1417871568,3287612,3211054559,3126306446,1975924523,1353700161,2814456437,2438597621,1800716203,722146342,2873936343,1151126914,4160483941,2877670899,458611604,2866078500,3483680063,770352098,2652916994,3367839148,3940505011,3585973912,3809620402,718646636,2504206814,2914927912,3631288169,2857486607,2860018678,575749918,2857478043,718488780,2069512688,3548183469,453416197,1106044049,3032691430,52586708,3378514636,3459808877,3211506028,1785789304,218356169,3571399134,3759170522,1194783844,1523787992,3007827094,1975193539,2555452411,1341901877,3045838698,3776907964,3217423946,2802510864,2889438986,1057244207,1636348243,3761863214,1462225785,2632663439,481089165,718503062,24497053,3332243209,3344655856,3655024856,3960371065,1195698900,2971415156,3710176158,2115785917,4027663609,3525578417,2524296189,2745972565,3564906415,1372086093,1452307862,2780501478,1476592880,3389271281,18495466,2378148571,901398090,891748256,3279637769,3157290713,2560960102,1447622437,4284372637,216884176,2086908623,1879786977,3588903153,2242455666,2938092967,3559082096,2810645491,758861177,1121993112,215018983,642190776,4169236812,1196255959,2081185372,3508738393,941322904,4124243163,2877523539,1848581667,2205260958,3180453958,2589345134,3694731276,550028657,2519456284,3789985535,2973870856,2093648313,443148163,46942275,2734146937,1117713533,1115362972,1523183689,3717140224,1551984063),f[1]=new Array(522195092,4010518363,1776537470,960447360,4267822970,4005896314,1435016340,1929119313,2913464185,1310552629,3579470798,3724818106,2579771631,1594623892,417127293,2715217907,2696228731,1508390405,3994398868,3925858569,3695444102,4019471449,3129199795,3770928635,3520741761,990456497,4187484609,2783367035,21106139,3840405339,631373633,3783325702,532942976,396095098,3548038825,4267192484,2564721535,2011709262,2039648873,620404603,3776170075,2898526339,3612357925,4159332703,1645490516,223693667,1567101217,3362177881,1029951347,3470931136,3570957959,1550265121,119497089,972513919,907948164,3840628539,1613718692,3594177948,465323573,2659255085,654439692,2575596212,2699288441,3127702412,277098644,624404830,4100943870,2717858591,546110314,2403699828,3655377447,1321679412,4236791657,1045293279,4010672264,895050893,2319792268,494945126,1914543101,2777056443,3894764339,2219737618,311263384,4275257268,3458730721,669096869,3584475730,3835122877,3319158237,3949359204,2005142349,2713102337,2228954793,3769984788,569394103,3855636576,1425027204,108000370,2736431443,3671869269,3043122623,1750473702,2211081108,762237499,3972989403,2798899386,3061857628,2943854345,867476300,964413654,1591880597,1594774276,2179821409,552026980,3026064248,3726140315,2283577634,3110545105,2152310760,582474363,1582640421,1383256631,2043843868,3322775884,1217180674,463797851,2763038571,480777679,2718707717,2289164131,3118346187,214354409,200212307,3810608407,3025414197,2674075964,3997296425,1847405948,1342460550,510035443,4080271814,815934613,833030224,1620250387,1945732119,2703661145,3966000196,1388869545,3456054182,2687178561,2092620194,562037615,1356438536,3409922145,3261847397,1688467115,2150901366,631725691,3840332284,549916902,3455104640,394546491,837744717,2114462948,751520235,2221554606,2415360136,3999097078,2063029875,803036379,2702586305,821456707,3019566164,360699898,4018502092,3511869016,3677355358,2402471449,812317050,49299192,2570164949,3259169295,2816732080,3331213574,3101303564,2156015656,3705598920,3546263921,143268808,3200304480,1638124008,3165189453,3341807610,578956953,2193977524,3638120073,2333881532,807278310,658237817,2969561766,1641658566,11683945,3086995007,148645947,1138423386,4158756760,1981396783,2401016740,3699783584,380097457,2680394679,2803068651,3334260286,441530178,4016580796,1375954390,761952171,891809099,2183123478,157052462,3683840763,1592404427,341349109,2438483839,1417898363,644327628,2233032776,2353769706,2201510100,220455161,1815641738,182899273,2995019788,3627381533,3702638151,2890684138,1052606899,588164016,1681439879,4038439418,2405343923,4229449282,167996282,1336969661,1688053129,2739224926,1543734051,1046297529,1138201970,2121126012,115334942,1819067631,1902159161,1941945968,2206692869,1159982321),f[2]=new Array(2381300288,637164959,3952098751,3893414151,1197506559,916448331,2350892612,2932787856,3199334847,4009478890,3905886544,1373570990,2450425862,4037870920,3778841987,2456817877,286293407,124026297,3001279700,1028597854,3115296800,4208886496,2691114635,2188540206,1430237888,1218109995,3572471700,308166588,570424558,2187009021,2455094765,307733056,1310360322,3135275007,1384269543,2388071438,863238079,2359263624,2801553128,3380786597,2831162807,1470087780,1728663345,4072488799,1090516929,532123132,2389430977,1132193179,2578464191,3051079243,1670234342,1434557849,2711078940,1241591150,3314043432,3435360113,3091448339,1812415473,2198440252,267246943,796911696,3619716990,38830015,1526438404,2806502096,374413614,2943401790,1489179520,1603809326,1920779204,168801282,260042626,2358705581,1563175598,2397674057,1356499128,2217211040,514611088,2037363785,2186468373,4022173083,2792511869,2913485016,1173701892,4200428547,3896427269,1334932762,2455136706,602925377,2835607854,1613172210,41346230,2499634548,2457437618,2188827595,41386358,4172255629,1313404830,2405527007,3801973774,2217704835,873260488,2528884354,2478092616,4012915883,2555359016,2006953883,2463913485,575479328,2218240648,2099895446,660001756,2341502190,3038761536,3888151779,3848713377,3286851934,1022894237,1620365795,3449594689,1551255054,15374395,3570825345,4249311020,4151111129,3181912732,310226346,1133119310,530038928,136043402,2476768958,3107506709,2544909567,1036173560,2367337196,1681395281,1758231547,3641649032,306774401,1575354324,3716085866,1990386196,3114533736,2455606671,1262092282,3124342505,2768229131,4210529083,1833535011,423410938,660763973,2187129978,1639812e3,3508421329,3467445492,310289298,272797111,2188552562,2456863912,310240523,677093832,1013118031,901835429,3892695601,1116285435,3036471170,1337354835,243122523,520626091,277223598,4244441197,4194248841,1766575121,594173102,316590669,742362309,3536858622,4176435350,3838792410,2501204839,1229605004,3115755532,1552908988,2312334149,979407927,3959474601,1148277331,176638793,3614686272,2083809052,40992502,1340822838,2731552767,3535757508,3560899520,1354035053,122129617,7215240,2732932949,3118912700,2718203926,2539075635,3609230695,3725561661,1928887091,2882293555,1988674909,2063640240,2491088897,1459647954,4189817080,2302804382,1113892351,2237858528,1927010603,4002880361,1856122846,1594404395,2944033133,3855189863,3474975698,1643104450,4054590833,3431086530,1730235576,2984608721,3084664418,2131803598,4178205752,267404349,1617849798,1616132681,1462223176,736725533,2327058232,551665188,2945899023,1749386277,2575514597,1611482493,674206544,2201269090,3642560800,728599968,1680547377,2620414464,1388111496,453204106,4156223445,1094905244,2754698257,2201108165,3757000246,2704524545,3922940700,3996465027),f[3]=new Array(2645754912,532081118,2814278639,3530793624,1246723035,1689095255,2236679235,4194438865,2116582143,3859789411,157234593,2045505824,4245003587,1687664561,4083425123,605965023,672431967,1336064205,3376611392,214114848,4258466608,3232053071,489488601,605322005,3998028058,264917351,1912574028,756637694,436560991,202637054,135989450,85393697,2152923392,3896401662,2895836408,2145855233,3535335007,115294817,3147733898,1922296357,3464822751,4117858305,1037454084,2725193275,2127856640,1417604070,1148013728,1827919605,642362335,2929772533,909348033,1346338451,3547799649,297154785,1917849091,4161712827,2883604526,3968694238,1469521537,3780077382,3375584256,1763717519,136166297,4290970789,1295325189,2134727907,2798151366,1566297257,3672928234,2677174161,2672173615,965822077,2780786062,289653839,1133871874,3491843819,35685304,1068898316,418943774,672553190,642281022,2346158704,1954014401,3037126780,4079815205,2030668546,3840588673,672283427,1776201016,359975446,3750173538,555499703,2769985273,1324923,69110472,152125443,3176785106,3822147285,1340634837,798073664,1434183902,15393959,216384236,1303690150,3881221631,3711134124,3960975413,106373927,2578434224,1455997841,1801814300,1578393881,1854262133,3188178946,3258078583,2302670060,1539295533,3505142565,3078625975,2372746020,549938159,3278284284,2620926080,181285381,2865321098,3970029511,68876850,488006234,1728155692,2608167508,836007927,2435231793,919367643,3339422534,3655756360,1457871481,40520939,1380155135,797931188,234455205,2255801827,3990488299,397000196,739833055,3077865373,2871719860,4022553888,772369276,390177364,3853951029,557662966,740064294,1640166671,1699928825,3535942136,622006121,3625353122,68743880,1742502,219489963,1664179233,1577743084,1236991741,410585305,2366487942,823226535,1050371084,3426619607,3586839478,212779912,4147118561,1819446015,1911218849,530248558,3486241071,3252585495,2886188651,3410272728,2342195030,20547779,2982490058,3032363469,3631753222,312714466,1870521650,1493008054,3491686656,615382978,4103671749,2534517445,1932181,2196105170,278426614,6369430,3274544417,2913018367,697336853,2143000447,2946413531,701099306,1558357093,2805003052,3500818408,2321334417,3567135975,216290473,3591032198,23009561,1996984579,3735042806,2024298078,3739440863,569400510,2339758983,3016033873,3097871343,3639523026,3844324983,3256173865,795471839,2951117563,4101031090,4091603803,3603732598,971261452,534414648,428311343,3389027175,2844869880,694888862,1227866773,2456207019,3043454569,2614353370,3749578031,3676663836,459166190,4132644070,1794958188,51825668,2252611902,3084671440,2036672799,3436641603,1099053433,2469121526,3059204941,1323291266,2061838604,1018778475,2233344254,2553501054,334295216,3556750194,1065731521,183467730),f[4]=new Array(2127105028,745436345,2601412319,2788391185,3093987327,500390133,1155374404,389092991,150729210,3891597772,3523549952,1935325696,716645080,946045387,2901812282,1774124410,3869435775,4039581901,3293136918,3438657920,948246080,363898952,3867875531,1286266623,1598556673,68334250,630723836,1104211938,1312863373,613332731,2377784574,1101634306,441780740,3129959883,1917973735,2510624549,3238456535,2544211978,3308894634,1299840618,4076074851,1756332096,3977027158,297047435,3790297736,2265573040,3621810518,1311375015,1667687725,47300608,3299642885,2474112369,201668394,1468347890,576830978,3594690761,3742605952,1958042578,1747032512,3558991340,1408974056,3366841779,682131401,1033214337,1545599232,4265137049,206503691,103024618,2855227313,1337551222,2428998917,2963842932,4015366655,3852247746,2796956967,3865723491,3747938335,247794022,3755824572,702416469,2434691994,397379957,851939612,2314769512,218229120,1380406772,62274761,214451378,3170103466,2276210409,3845813286,28563499,446592073,1693330814,3453727194,29968656,3093872512,220656637,2470637031,77972100,1667708854,1358280214,4064765667,2395616961,325977563,4277240721,4220025399,3605526484,3355147721,811859167,3069544926,3962126810,652502677,3075892249,4132761541,3498924215,1217549313,3250244479,3858715919,3053989961,1538642152,2279026266,2875879137,574252750,3324769229,2651358713,1758150215,141295887,2719868960,3515574750,4093007735,4194485238,1082055363,3417560400,395511885,2966884026,179534037,3646028556,3738688086,1092926436,2496269142,257381841,3772900718,1636087230,1477059743,2499234752,3811018894,2675660129,3285975680,90732309,1684827095,1150307763,1723134115,3237045386,1769919919,1240018934,815675215,750138730,2239792499,1234303040,1995484674,138143821,675421338,1145607174,1936608440,3238603024,2345230278,2105974004,323969391,779555213,3004902369,2861610098,1017501463,2098600890,2628620304,2940611490,2682542546,1171473753,3656571411,3687208071,4091869518,393037935,159126506,1662887367,1147106178,391545844,3452332695,1891500680,3016609650,1851642611,546529401,1167818917,3194020571,2848076033,3953471836,575554290,475796850,4134673196,450035699,2351251534,844027695,1080539133,86184846,1554234488,3692025454,1972511363,2018339607,1491841390,1141460869,1061690759,4244549243,2008416118,2351104703,2868147542,1598468138,722020353,1027143159,212344630,1387219594,1725294528,3745187956,2500153616,458938280,4129215917,1828119673,544571780,3503225445,2297937496,1241802790,267843827,2694610800,1397140384,1558801448,3782667683,1806446719,929573330,2234912681,400817706,616011623,4121520928,3603768725,1761550015,1968522284,4053731006,4192232858,4005120285,872482584,3140537016,3894607381,2287405443,1963876937,3663887957,1584857e3,2975024454,1833426440,4025083860),f[5]=new Array(4143615901,749497569,1285769319,3795025788,2514159847,23610292,3974978748,844452780,3214870880,3751928557,2213566365,1676510905,448177848,3730751033,4086298418,2307502392,871450977,3222878141,4110862042,3831651966,2735270553,1310974780,2043402188,1218528103,2736035353,4274605013,2702448458,3936360550,2693061421,162023535,2827510090,687910808,23484817,3784910947,3371371616,779677500,3503626546,3473927188,4157212626,3500679282,4248902014,2466621104,3899384794,1958663117,925738300,1283408968,3669349440,1840910019,137959847,2679828185,1239142320,1315376211,1547541505,1690155329,739140458,3128809933,3933172616,3876308834,905091803,1548541325,4040461708,3095483362,144808038,451078856,676114313,2861728291,2469707347,993665471,373509091,2599041286,4025009006,4170239449,2149739950,3275793571,3749616649,2794760199,1534877388,572371878,2590613551,1753320020,3467782511,1405125690,4270405205,633333386,3026356924,3475123903,632057672,2846462855,1404951397,3882875879,3915906424,195638627,2385783745,3902872553,1233155085,3355999740,2380578713,2702246304,2144565621,3663341248,3894384975,2502479241,4248018925,3094885567,1594115437,572884632,3385116731,767645374,1331858858,1475698373,3793881790,3532746431,1321687957,619889600,1121017241,3440213920,2070816767,2833025776,1933951238,4095615791,890643334,3874130214,859025556,360630002,925594799,1764062180,3920222280,4078305929,979562269,2810700344,4087740022,1949714515,546639971,1165388173,3069891591,1495988560,922170659,1291546247,2107952832,1813327274,3406010024,3306028637,4241950635,153207855,2313154747,1608695416,1150242611,1967526857,721801357,1220138373,3691287617,3356069787,2112743302,3281662835,1111556101,1778980689,250857638,2298507990,673216130,2846488510,3207751581,3562756981,3008625920,3417367384,2198807050,529510932,3547516680,3426503187,2364944742,102533054,2294910856,1617093527,1204784762,3066581635,1019391227,1069574518,1317995090,1691889997,3661132003,510022745,3238594800,1362108837,1817929911,2184153760,805817662,1953603311,3699844737,120799444,2118332377,207536705,2282301548,4120041617,145305846,2508124933,3086745533,3261524335,1877257368,2977164480,3160454186,2503252186,4221677074,759945014,254147243,2767453419,3801518371,629083197,2471014217,907280572,3900796746,940896768,2751021123,2625262786,3161476951,3661752313,3260732218,1425318020,2977912069,1496677566,3988592072,2140652971,3126511541,3069632175,977771578,1392695845,1698528874,1411812681,1369733098,1343739227,3620887944,1142123638,67414216,3102056737,3088749194,1626167401,2546293654,3941374235,697522451,33404913,143560186,2595682037,994885535,1247667115,3859094837,2699155541,3547024625,4114935275,2968073508,3199963069,2732024527,1237921620,951448369,1898488916,1211705605,2790989240,2233243581,3598044975),f[6]=new Array(2246066201,858518887,1714274303,3485882003,713916271,2879113490,3730835617,539548191,36158695,1298409750,419087104,1358007170,749914897,2989680476,1261868530,2995193822,2690628854,3443622377,3780124940,3796824509,2976433025,4259637129,1551479e3,512490819,1296650241,951993153,2436689437,2460458047,144139966,3136204276,310820559,3068840729,643875328,1969602020,1680088954,2185813161,3283332454,672358534,198762408,896343282,276269502,3014846926,84060815,197145886,376173866,3943890818,3813173521,3545068822,1316698879,1598252827,2633424951,1233235075,859989710,2358460855,3503838400,3409603720,1203513385,1193654839,2792018475,2060853022,207403770,1144516871,3068631394,1121114134,177607304,3785736302,326409831,1929119770,2983279095,4183308101,3474579288,3200513878,3228482096,119610148,1170376745,3378393471,3163473169,951863017,3337026068,3135789130,2907618374,1183797387,2015970143,4045674555,2182986399,2952138740,3928772205,384012900,2454997643,10178499,2879818989,2596892536,111523738,2995089006,451689641,3196290696,235406569,1441906262,3890558523,3013735005,4158569349,1644036924,376726067,1006849064,3664579700,2041234796,1021632941,1374734338,2566452058,371631263,4007144233,490221539,206551450,3140638584,1053219195,1853335209,3412429660,3562156231,735133835,1623211703,3104214392,2738312436,4096837757,3366392578,3110964274,3956598718,3196820781,2038037254,3877786376,2339753847,300912036,3766732888,2372630639,1516443558,4200396704,1574567987,4069441456,4122592016,2699739776,146372218,2748961456,2043888151,35287437,2596680554,655490400,1132482787,110692520,1031794116,2188192751,1324057718,1217253157,919197030,686247489,3261139658,1028237775,3135486431,3059715558,2460921700,986174950,2661811465,4062904701,2752986992,3709736643,367056889,1353824391,731860949,1650113154,1778481506,784341916,357075625,3608602432,1074092588,2480052770,3811426202,92751289,877911070,3600361838,1231880047,480201094,3756190983,3094495953,434011822,87971354,363687820,1717726236,1901380172,3926403882,2481662265,400339184,1490350766,2661455099,1389319756,2558787174,784598401,1983468483,30828846,3550527752,2716276238,3841122214,1765724805,1955612312,1277890269,1333098070,1564029816,2704417615,1026694237,3287671188,1260819201,3349086767,1016692350,1582273796,1073413053,1995943182,694588404,1025494639,3323872702,3551898420,4146854327,453260480,1316140391,1435673405,3038941953,3486689407,1622062951,403978347,817677117,950059133,4246079218,3278066075,1486738320,1417279718,481875527,2549965225,3933690356,760697757,1452955855,3897451437,1177426808,1702951038,4085348628,2447005172,1084371187,3516436277,3068336338,1073369276,1027665953,3284188590,1230553676,1368340146,2226246512,267243139,2274220762,4070734279,2497715176,2423353163,2504755875),f[7]=new Array(3793104909,3151888380,2817252029,895778965,2005530807,3871412763,237245952,86829237,296341424,3851759377,3974600970,2475086196,709006108,1994621201,2972577594,937287164,3734691505,168608556,3189338153,2225080640,3139713551,3033610191,3025041904,77524477,185966941,1208824168,2344345178,1721625922,3354191921,1066374631,1927223579,1971335949,2483503697,1551748602,2881383779,2856329572,3003241482,48746954,1398218158,2050065058,313056748,4255789917,393167848,1912293076,940740642,3465845460,3091687853,2522601570,2197016661,1727764327,364383054,492521376,1291706479,3264136376,1474851438,1685747964,2575719748,1619776915,1814040067,970743798,1561002147,2925768690,2123093554,1880132620,3151188041,697884420,2550985770,2607674513,2659114323,110200136,1489731079,997519150,1378877361,3527870668,478029773,2766872923,1022481122,431258168,1112503832,897933369,2635587303,669726182,3383752315,918222264,163866573,3246985393,3776823163,114105080,1903216136,761148244,3571337562,1690750982,3166750252,1037045171,1888456500,2010454850,642736655,616092351,365016990,1185228132,4174898510,1043824992,2023083429,2241598885,3863320456,3279669087,3674716684,108438443,2132974366,830746235,606445527,4173263986,2204105912,1844756978,2532684181,4245352700,2969441100,3796921661,1335562986,4061524517,2720232303,2679424040,634407289,885462008,3294724487,3933892248,2094100220,339117932,4048830727,3202280980,1458155303,2689246273,1022871705,2464987878,3714515309,353796843,2822958815,4256850100,4052777845,551748367,618185374,3778635579,4020649912,1904685140,3069366075,2670879810,3407193292,2954511620,4058283405,2219449317,3135758300,1120655984,3447565834,1474845562,3577699062,550456716,3466908712,2043752612,881257467,869518812,2005220179,938474677,3305539448,3850417126,1315485940,3318264702,226533026,965733244,321539988,1136104718,804158748,573969341,3708209826,937399083,3290727049,2901666755,1461057207,4013193437,4066861423,3242773476,2421326174,1581322155,3028952165,786071460,3900391652,3918438532,1485433313,4023619836,3708277595,3678951060,953673138,1467089153,1930354364,1533292819,2492563023,1346121658,1685000834,1965281866,3765933717,4190206607,2052792609,3515332758,690371149,3125873887,2180283551,2903598061,3933952357,436236910,289419410,14314871,1242357089,2904507907,1616633776,2666382180,585885352,3471299210,2699507360,1432659641,277164553,3354103607,770115018,2303809295,3741942315,3177781868,2853364978,2269453327,3774259834,987383833,1290892879,225909803,1741533526,890078084,1496906255,1111072499,916028167,243534141,1252605537,2204162171,531204876,290011180,3916834213,102027703,237315147,209093447,1486785922,220223953,2758195998,4175039106,82940208,3127791296,2569425252,518464269,1353887104,3941492737,2377294467,3935040926)}function d(a){this.cast5=new c,this.cast5.setKey(e.str2bin(a)),this.encrypt=function(a){return this.cast5.encrypt(a)}}var e=a("../../util.js");b.exports=d,b.exports.blockSize=d.prototype.blockSize=8,b.exports.keySize=d.prototype.keySize=16},{"../../util.js":61}],9:[function(a,b){function c(a,b,c,d,g,h){var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w=new Array(16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028,16778240,16778240,0,65540,66560,0,16842756),x=new Array(-2146402272,-2147450880,32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576,-2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880,32800,-2147483648,-2146435040,-2146402272,1081344),y=new Array(520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072,134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800,131592,8,134348808,131584),z=new Array(8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928),A=new Array(256,34078976,34078720,1107296512,524288,256,1073741824,34078720,1074266368,524288,33554688,1074266368,1107296512,1107820544,524544,1073741824,33554432,1074266112,1074266112,0,1073742080,1107820800,1107820800,33554688,1107820544,1073742080,0,1107296256,34078976,33554432,1107296256,524544,524288,1107296512,256,33554432,1073741824,34078720,1107296512,1074266368,33554688,1073741824,1107820544,34078976,1074266368,256,33554432,1107820544,1107820800,524544,1107296256,1107820800,34078720,0,1074266112,1107296256,524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080),B=new Array(536870928,541065216,16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384,541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312),C=new Array(2097152,69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066,0,2099202,69206016,2048,67108866,67110912,2048,2097154),D=new Array(268439616,4096,262144,268701760,268435456,268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240,266240,4160,4160,262208,268435456,268701696),E=0,F=b.length,G=0,H=32==a.length?3:9; -for(p=3==H?c?new Array(0,32,2):new Array(30,-2,-2):c?new Array(0,32,2,62,30,-2,64,96,2):new Array(94,62,-2,32,64,2,30,-2,-2),c&&(b=e(b,h),F=b.length),result="",tempresult="",1==d&&(q=g.charCodeAt(E++)<<24|g.charCodeAt(E++)<<16|g.charCodeAt(E++)<<8|g.charCodeAt(E++),s=g.charCodeAt(E++)<<24|g.charCodeAt(E++)<<16|g.charCodeAt(E++)<<8|g.charCodeAt(E++),E=0);F>E;){for(n=b.charCodeAt(E++)<<24|b.charCodeAt(E++)<<16|b.charCodeAt(E++)<<8|b.charCodeAt(E++),o=b.charCodeAt(E++)<<24|b.charCodeAt(E++)<<16|b.charCodeAt(E++)<<8|b.charCodeAt(E++),1==d&&(c?(n^=q,o^=s):(r=q,t=s,q=n,s=o)),k=252645135&(n>>>4^o),o^=k,n^=k<<4,k=65535&(n>>>16^o),o^=k,n^=k<<16,k=858993459&(o>>>2^n),n^=k,o^=k<<2,k=16711935&(o>>>8^n),n^=k,o^=k<<8,k=1431655765&(n>>>1^o),o^=k,n^=k<<1,n=n<<1|n>>>31,o=o<<1|o>>>31,j=0;H>j;j+=3){for(u=p[j+1],v=p[j+2],i=p[j];i!=u;i+=v)l=o^a[i],m=(o>>>4|o<<28)^a[i+1],k=n,n=o,o=k^(x[l>>>24&63]|z[l>>>16&63]|B[l>>>8&63]|D[63&l]|w[m>>>24&63]|y[m>>>16&63]|A[m>>>8&63]|C[63&m]);k=n,n=o,o=k}n=n>>>1|n<<31,o=o>>>1|o<<31,k=1431655765&(n>>>1^o),o^=k,n^=k<<1,k=16711935&(o>>>8^n),n^=k,o^=k<<8,k=858993459&(o>>>2^n),n^=k,o^=k<<2,k=65535&(n>>>16^o),o^=k,n^=k<<16,k=252645135&(n>>>4^o),o^=k,n^=k<<4,1==d&&(c?(q=n,s=o):(n^=r,o^=t)),tempresult+=String.fromCharCode(n>>>24,n>>>16&255,n>>>8&255,255&n,o>>>24,o>>>16&255,o>>>8&255,255&o),G+=8,512==G&&(result+=tempresult,tempresult="",G=0)}return result+=tempresult,c||(result=f(result,h)),result}function d(a){pc2bytes0=new Array(0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964),pc2bytes1=new Array(0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697),pc2bytes2=new Array(0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272),pc2bytes3=new Array(0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144),pc2bytes4=new Array(0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256),pc2bytes5=new Array(0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488),pc2bytes6=new Array(0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746),pc2bytes7=new Array(0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568),pc2bytes8=new Array(0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578),pc2bytes9=new Array(0,268435456,8,268435464,0,268435456,8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488),pc2bytes10=new Array(0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800),pc2bytes11=new Array(0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744),pc2bytes12=new Array(0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128),pc2bytes13=new Array(0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261);for(var b,c,d,e=a.length>8?3:1,f=new Array(32*e),g=new Array(0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0),h=0,j=0,k=0;e>k;k++)for(left=a.charCodeAt(h++)<<24|a.charCodeAt(h++)<<16|a.charCodeAt(h++)<<8|a.charCodeAt(h++),right=a.charCodeAt(h++)<<24|a.charCodeAt(h++)<<16|a.charCodeAt(h++)<<8|a.charCodeAt(h++),d=252645135&(left>>>4^right),right^=d,left^=d<<4,d=65535&(right>>>-16^left),left^=d,right^=d<<-16,d=858993459&(left>>>2^right),right^=d,left^=d<<2,d=65535&(right>>>-16^left),left^=d,right^=d<<-16,d=1431655765&(left>>>1^right),right^=d,left^=d<<1,d=16711935&(right>>>8^left),left^=d,right^=d<<8,d=1431655765&(left>>>1^right),right^=d,left^=d<<1,d=left<<8|right>>>20&240,left=right<<24|right<<8&16711680|right>>>8&65280|right>>>24&240,right=d,i=0;i>>26,right=right<<2|right>>>26):(left=left<<1|left>>>27,right=right<<1|right>>>27),left&=-15,right&=-15,b=pc2bytes0[left>>>28]|pc2bytes1[left>>>24&15]|pc2bytes2[left>>>20&15]|pc2bytes3[left>>>16&15]|pc2bytes4[left>>>12&15]|pc2bytes5[left>>>8&15]|pc2bytes6[left>>>4&15],c=pc2bytes7[right>>>28]|pc2bytes8[right>>>24&15]|pc2bytes9[right>>>20&15]|pc2bytes10[right>>>16&15]|pc2bytes11[right>>>12&15]|pc2bytes12[right>>>8&15]|pc2bytes13[right>>>4&15],d=65535&(c>>>16^b),f[j++]=b^d,f[j++]=c^d<<16;return f}function e(a,b){var c=8-a.length%8;return 2==b&&8>c?a+=" ".substr(0,c):1==b?a+=String.fromCharCode(c,c,c,c,c,c,c,c).substr(0,c):!b&&8>c&&(a+="\x00\x00\x00\x00\x00\x00\x00\x00".substr(0,c)),a}function f(a,b){if(2==b)a=a.replace(/ *$/g,"");else if(1==b){var c=a.charCodeAt(a.length-1);a=a.substr(0,a.length-c)}else b||(a=a.replace(/\0*$/g,""));return a}function g(a){this.key=[];for(var b=0;3>b;b++)this.key.push(a.substr(8*b,8));this.encrypt=function(a){return j.str2bin(c(d(this.key[2]),c(d(this.key[1]),c(d(this.key[0]),j.bin2str(a),!0,0,null,null),!1,0,null,null),!0,0,null,null))}}function h(a){this.key=a,this.encrypt=function(a,b){var e=d(this.key);return j.str2bin(c(e,j.bin2str(a),!0,0,null,b))},this.decrypt=function(a,b){var e=d(this.key);return j.str2bin(c(e,j.bin2str(a),!1,0,null,b))}}var j=a("../../util.js");g.keySize=g.prototype.keySize=24,g.blockSize=g.prototype.blockSize=8,b.exports={des:g,originalDes:h}},{"../../util.js":61}],10:[function(a,b){var c=a("./des.js");b.exports={des:c.originalDes,tripledes:c.des,cast5:a("./cast5.js"),twofish:a("./twofish.js"),blowfish:a("./blowfish.js"),idea:function(){throw new Error("IDEA symmetric-key algorithm not implemented")}};var d=a("./aes.js");for(var e in d)b.exports["aes"+e]=d[e]},{"./aes.js":6,"./blowfish.js":7,"./cast5.js":8,"./des.js":9,"./twofish.js":11}],11:[function(a,b){function c(a,b){return(a<>>32-b)&i}function d(a,b){return a[b]|a[b+1]<<8|a[b+2]<<16|a[b+3]<<24}function e(a,b,c){a.splice(b,4,255&c,c>>>8&255,c>>>16&255,c>>>24&255)}function f(a,b){return a>>>8*b&255}function g(){function a(a){function b(a){return a^a>>2^[0,90,180,238][3&a]}function e(a){return a^a>>1^a>>2^[0,238,180,90][3&a]}function g(a,b){var c,d,e;for(c=0;8>c;c++)d=b>>>24,b=b<<8&i|a>>>24,a=a<<8&i,e=d<<1,128&d&&(e^=333),b^=d^e<<16,e^=d>>>1,1&d&&(e^=166),b^=e<<24|e<<8;return b}function h(a,b){var c,d,e,f;return c=b>>4,d=15&b,e=A[a][c^d],f=B[a][E[d]^F[c]],D[a][E[f]^F[e]]<<4|C[a][e^f]}function j(a,b){var c=f(a,0),d=f(a,1),e=f(a,2),g=f(a,3);switch(q){case 4:c=G[1][c]^f(b[3],0),d=G[0][d]^f(b[3],1),e=G[0][e]^f(b[3],2),g=G[1][g]^f(b[3],3);case 3:c=G[1][c]^f(b[2],0),d=G[1][d]^f(b[2],1),e=G[0][e]^f(b[2],2),g=G[0][g]^f(b[2],3);case 2:c=G[0][G[0][c]^f(b[1],0)]^f(b[0],0),d=G[0][G[1][d]^f(b[1],1)]^f(b[0],1),e=G[1][G[0][e]^f(b[1],2)]^f(b[0],2),g=G[1][G[1][g]^f(b[1],3)]^f(b[0],3)}return H[0][c]^H[1][d]^H[2][e]^H[3][g]}o=a;var k,l,m,n,p,q,r,u,v,w=[],x=[],y=[],z=[],A=[[8,1,7,13,6,15,3,2,0,11,5,9,14,12,10,4],[2,8,11,13,15,7,6,14,3,1,9,4,0,10,12,5]],B=[[14,12,11,8,1,2,3,5,15,4,10,6,7,0,9,13],[1,14,2,11,4,12,3,7,6,13,10,5,15,9,0,8]],C=[[11,10,5,14,6,13,9,0,12,8,15,3,2,4,7,1],[4,12,7,5,1,6,9,10,0,14,13,8,2,11,3,15]],D=[[13,7,15,4,1,2,6,14,9,11,3,0,8,5,12,10],[11,9,5,1,12,3,13,14,6,4,7,15,2,0,8,10]],E=[0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15],F=[0,9,2,11,4,13,6,15,8,1,10,3,12,5,14,7],G=[[],[]],H=[[],[],[],[]];for(o=o.slice(0,32),k=o.length;16!=k&&24!=k&&32!=k;)o[k++]=0;for(k=0;k>2]=d(o,k);for(k=0;256>k;k++)G[0][k]=h(0,k),G[1][k]=h(1,k);for(k=0;256>k;k++)r=G[1][k],u=b(r),v=e(r),H[0][k]=r+(u<<8)+(v<<16)+(v<<24),H[2][k]=u+(v<<8)+(r<<16)+(v<<24),r=G[0][k],u=b(r),v=e(r),H[1][k]=v+(v<<8)+(u<<16)+(r<<24),H[3][k]=u+(r<<8)+(v<<16)+(u<<24);for(q=y.length/2,k=0;q>k;k++)l=y[k+k],w[k]=l,m=y[k+k+1],x[k]=m,z[q-k-1]=g(l,m);for(k=0;40>k;k+=2)l=16843009*k,m=l+16843009,l=j(l,w),m=c(j(m,x),8),s[k]=l+m&i,s[k+1]=c(l+2*m,9);for(k=0;256>k;k++)switch(l=m=n=p=k,q){case 4:l=G[1][l]^f(z[3],0),m=G[0][m]^f(z[3],1),n=G[0][n]^f(z[3],2),p=G[1][p]^f(z[3],3);case 3:l=G[1][l]^f(z[2],0),m=G[1][m]^f(z[2],1),n=G[0][n]^f(z[2],2),p=G[0][p]^f(z[2],3);case 2:t[0][k]=H[0][G[0][G[0][l]^f(z[1],0)]^f(z[0],0)],t[1][k]=H[1][G[0][G[1][m]^f(z[1],1)]^f(z[0],1)],t[2][k]=H[2][G[1][G[0][n]^f(z[1],2)]^f(z[0],2)],t[3][k]=H[3][G[1][G[1][p]^f(z[1],3)]^f(z[0],3)]}}function b(a){return t[0][f(a,0)]^t[1][f(a,1)]^t[2][f(a,2)]^t[3][f(a,3)]}function g(a){return t[0][f(a,3)]^t[1][f(a,0)]^t[2][f(a,1)]^t[3][f(a,2)]}function h(a,d){var e=b(d[0]),f=g(d[1]);d[2]=c(d[2]^e+f+s[4*a+8]&i,31),d[3]=c(d[3],1)^e+2*f+s[4*a+9]&i,e=b(d[2]),f=g(d[3]),d[0]=c(d[0]^e+f+s[4*a+10]&i,31),d[1]=c(d[1],1)^e+2*f+s[4*a+11]&i}function j(a,d){var e=b(d[0]),f=g(d[1]);d[2]=c(d[2],1)^e+f+s[4*a+10]&i,d[3]=c(d[3]^e+2*f+s[4*a+11]&i,31),e=b(d[2]),f=g(d[3]),d[0]=c(d[0],1)^e+f+s[4*a+8]&i,d[1]=c(d[1]^e+2*f+s[4*a+9]&i,31)}function k(){s=[],t=[[],[],[],[]]}function l(a,b){p=a,q=b;for(var c=[d(p,q)^s[0],d(p,q+4)^s[1],d(p,q+8)^s[2],d(p,q+12)^s[3]],f=0;8>f;f++)h(f,c);return e(p,q,c[2]^s[4]),e(p,q+4,c[3]^s[5]),e(p,q+8,c[0]^s[6]),e(p,q+12,c[1]^s[7]),q+=16,p}function m(a,b){p=a,q=b;for(var c=[d(p,q)^s[4],d(p,q+4)^s[5],d(p,q+8)^s[6],d(p,q+12)^s[7]],f=7;f>=0;f--)j(f,c);e(p,q,c[2]^s[0]),e(p,q+4,c[3]^s[1]),e(p,q+8,c[0]^s[2]),e(p,q+12,c[1]^s[3]),q+=16}function n(){return p}var o=null,p=null,q=-1,r=null;r="twofish";var s=[],t=[[],[],[],[]];return{name:"twofish",blocksize:16,open:a,close:k,encrypt:l,decrypt:m,finalize:n}}function h(a){this.tf=g(),this.tf.open(j.str2bin(a),0),this.encrypt=function(a){return this.tf.encrypt([].concat(a),0)}}var i=4294967295,j=a("../../util.js");b.exports=h,b.exports.keySize=h.prototype.keySize=32,b.exports.blockSize=h.prototype.blockSize=16},{"../../util.js":61}],12:[function(a,b){var c=a("./random.js"),d=a("./cipher"),e=a("./public_key"),f=a("../type/mpi.js");b.exports={publicKeyEncrypt:function(a,b,c){var d=function(){var d;switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":var f=new e.rsa,g=b[0].toBigInteger(),h=b[1].toBigInteger();return d=c.toBigInteger(),[f.encrypt(d,h,g)];case"elgamal":var i=new e.elgamal,j=b[0].toBigInteger(),k=b[1].toBigInteger(),l=b[2].toBigInteger();return d=c.toBigInteger(),i.encrypt(d,k,j,l);default:return[]}}();return d.map(function(a){var b=new f;return b.fromBigInteger(a),b})},publicKeyDecrypt:function(a,b,c){var d,g=function(){switch(a){case"rsa_encrypt_sign":case"rsa_encrypt":var f=new e.rsa,g=b[0].toBigInteger(),h=b[1].toBigInteger(),i=b[2].toBigInteger();d=b[3].toBigInteger();var j=b[4].toBigInteger(),k=b[5].toBigInteger(),l=c[0].toBigInteger();return f.decrypt(l,g,h,i,d,j,k);case"elgamal":var m=new e.elgamal,n=b[3].toBigInteger(),o=c[0].toBigInteger(),p=c[1].toBigInteger();return d=b[0].toBigInteger(),m.decrypt(o,p,d,n);default:return null}}(),h=new f;return h.fromBigInteger(g),h},getPrivateMpiCount:function(a){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 4;case"elgamal":return 1;case"dsa":return 1;default:throw new Error("Unknown algorithm")}},getPublicMpiCount:function(a){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 2;case"elgamal":return 3;case"dsa":return 4;default:throw new Error("Unknown algorithm.")}},generateMpi:function(a,b){var c=function(){switch(a){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":var c=new e.rsa,d=c.generate(b,"10001"),f=[];return f.push(d.n),f.push(d.ee),f.push(d.d),f.push(d.p),f.push(d.q),f.push(d.u),f;default:throw new Error("Unsupported algorithm for key generation.")}}();return c.map(function(a){var b=new f;return b.fromBigInteger(a),b})},getPrefixRandom:function(a){return c.getRandomBytes(d[a].blockSize)},generateSessionKey:function(a){return c.getRandomBytes(d[a].keySize)}}},{"../type/mpi.js":59,"./cipher":10,"./public_key":23,"./random.js":26}],13:[function(a,b){var c=b.exports={},d=a("./forge_util.js"),e=null,f=!1,g=null,h=function(){e=String.fromCharCode(128),e+=d.fillString(String.fromCharCode(0),64),g=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],f=!0},i=function(a,b,c){for(var d,e,f,h,i,j,k,l,m,n,o,p,q,r,s,t=c.length();t>=64;){for(k=0;16>k;++k)b[k]=c.getInt32();for(;64>k;++k)d=b[k-2],d=(d>>>17|d<<15)^(d>>>19|d<<13)^d>>>10,e=b[k-15],e=(e>>>7|e<<25)^(e>>>18|e<<14)^e>>>3,b[k]=d+b[k-7]+e+b[k-16]&4294967295;for(l=a.h0,m=a.h1,n=a.h2,o=a.h3,p=a.h4,q=a.h5,r=a.h6,s=a.h7,k=0;64>k;++k)h=(p>>>6|p<<26)^(p>>>11|p<<21)^(p>>>25|p<<7),i=r^p&(q^r),f=(l>>>2|l<<30)^(l>>>13|l<<19)^(l>>>22|l<<10),j=l&m|n&(l^m),d=s+h+i+g[k]+b[k],e=f+j,s=r,r=q,q=p,p=o+d&4294967295,o=n,n=m,m=l,l=d+e&4294967295;a.h0=a.h0+l&4294967295,a.h1=a.h1+m&4294967295,a.h2=a.h2+n&4294967295,a.h3=a.h3+o&4294967295,a.h4=a.h4+p&4294967295,a.h5=a.h5+q&4294967295,a.h6=a.h6+r&4294967295,a.h7=a.h7+s&4294967295,t-=64}};c.create=function(){f||h();var a=null,b=d.createBuffer(),c=new Array(64),g={algorithm:"sha256",blockLength:64,digestLength:32,messageLength:0};return g.start=function(){return g.messageLength=0,b=d.createBuffer(),a={h0:1779033703,h1:3144134277,h2:1013904242,h3:2773480762,h4:1359893119,h5:2600822924,h6:528734635,h7:1541459225},g},g.start(),g.update=function(e,f){return"utf8"===f&&(e=d.encodeUtf8(e)),g.messageLength+=e.length,b.putBytes(e),i(a,c,b),(b.read>2048||0===b.length())&&b.compact(),g},g.digest=function(){var f=g.messageLength,h=d.createBuffer();h.putBytes(b.bytes()),h.putBytes(e.substr(0,64-(f+8)%64)),h.putInt32(f>>>29&255),h.putInt32(f<<3&4294967295);var j={h0:a.h0,h1:a.h1,h2:a.h2,h3:a.h3,h4:a.h4,h5:a.h5,h6:a.h6,h7:a.h7};i(j,c,h);var k=d.createBuffer();return k.putInt32(j.h0),k.putInt32(j.h1),k.putInt32(j.h2),k.putInt32(j.h3),k.putInt32(j.h4),k.putInt32(j.h5),k.putInt32(j.h6),k.putInt32(j.h7),k},g}},{"./forge_util.js":14}],14:[function(a,b){var c=b.exports={};c.isArray=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},c.isArrayBuffer=function(a){return"undefined"!=typeof ArrayBuffer&&a instanceof ArrayBuffer};var d=[];"undefined"!=typeof Int8Array&&d.push(Int8Array),"undefined"!=typeof Uint8Array&&d.push(Uint8Array),"undefined"!=typeof Uint8ClampedArray&&d.push(Uint8ClampedArray),"undefined"!=typeof Int16Array&&d.push(Int16Array),"undefined"!=typeof Uint16Array&&d.push(Uint16Array),"undefined"!=typeof Int32Array&&d.push(Int32Array),"undefined"!=typeof Uint32Array&&d.push(Uint32Array),"undefined"!=typeof Float32Array&&d.push(Float32Array),"undefined"!=typeof Float64Array&&d.push(Float64Array),c.isArrayBufferView=function(a){for(var b=0;b0;)1&b&&(c+=a),b>>>=1,b>0&&(a+=a);return this.data=c,this},c.ByteBuffer.prototype.putBytes=function(a){return this.data+=a,this},c.ByteBuffer.prototype.putString=function(a){return this.data+=c.encodeUtf8(a),this},c.ByteBuffer.prototype.putInt16=function(a){return this.data+=String.fromCharCode(a>>8&255)+String.fromCharCode(255&a),this},c.ByteBuffer.prototype.putInt24=function(a){return this.data+=String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(255&a),this},c.ByteBuffer.prototype.putInt32=function(a){return this.data+=String.fromCharCode(a>>24&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(255&a),this},c.ByteBuffer.prototype.putInt16Le=function(a){return this.data+=String.fromCharCode(255&a)+String.fromCharCode(a>>8&255),this},c.ByteBuffer.prototype.putInt24Le=function(a){return this.data+=String.fromCharCode(255&a)+String.fromCharCode(a>>8&255)+String.fromCharCode(a>>16&255),this},c.ByteBuffer.prototype.putInt32Le=function(a){return this.data+=String.fromCharCode(255&a)+String.fromCharCode(a>>8&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>24&255),this},c.ByteBuffer.prototype.putInt=function(a,b){do b-=8,this.data+=String.fromCharCode(a>>b&255);while(b>0);return this},c.ByteBuffer.prototype.putSignedInt=function(a,b){return 0>a&&(a+=2<0);return b},c.ByteBuffer.prototype.getSignedInt=function(a){var b=this.getInt(a),c=2<=c&&(b-=c<<1),b},c.ByteBuffer.prototype.getBytes=function(a){var b;return a?(a=Math.min(this.length(),a),b=this.data.slice(this.read,this.read+a),this.read+=a):0===a?b="":(b=0===this.read?this.data:this.data.slice(this.read),this.clear()),b},c.ByteBuffer.prototype.bytes=function(a){return"undefined"==typeof a?this.data.slice(this.read):this.data.slice(this.read,this.read+a)},c.ByteBuffer.prototype.at=function(a){return this.data.charCodeAt(this.read+a)},c.ByteBuffer.prototype.setAt=function(a,b){return this.data=this.data.substr(0,this.read+a)+String.fromCharCode(b)+this.data.substr(this.read+a+1),this},c.ByteBuffer.prototype.last=function(){return this.data.charCodeAt(this.data.length-1)},c.ByteBuffer.prototype.copy=function(){var a=c.createBuffer(this.data);return a.read=this.read,a},c.ByteBuffer.prototype.compact=function(){return this.read>0&&(this.data=this.data.slice(this.read),this.read=0),this},c.ByteBuffer.prototype.clear=function(){return this.data="",this.read=0,this},c.ByteBuffer.prototype.truncate=function(a){var b=Math.max(0,this.length()-a);return this.data=this.data.substr(this.read,b),this.read=0,this},c.ByteBuffer.prototype.toHex=function(){for(var a="",b=this.read;bc&&(a+="0"),a+=c.toString(16)}return a},c.ByteBuffer.prototype.toString=function(){return c.decodeUtf8(this.bytes())},c.createBuffer=function(a,b){return b=b||"raw",void 0!==a&&"utf8"===b&&(a=c.encodeUtf8(a)),new c.ByteBuffer(a)},c.fillString=function(a,b){for(var c="";b>0;)1&b&&(c+=a),b>>>=1,b>0&&(a+=a);return c},c.xorBytes=function(a,b,c){for(var d="",e="",f="",g=0,h=0;c>0;--c,++g)e=a.charCodeAt(g)^b.charCodeAt(g),h>=10&&(d+=f,f="",h=0),f+=String.fromCharCode(e),++h;return d+=f},c.hexToBytes=function(a){var b="",c=0;for(a.length&!0&&(c=1,b+=String.fromCharCode(parseInt(a[0],16)));c>24&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(255&a)};var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",f=[62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];c.encode64=function(a,b){for(var c,d,f,g="",h="",i=0;i>2),g+=e.charAt((3&c)<<4|d>>4),isNaN(d)?g+="==":(g+=e.charAt((15&d)<<2|f>>6),g+=isNaN(f)?"=":e.charAt(63&f)),b&&g.length>b&&(h+=g.substr(0,b)+"\r\n",g=g.substr(b));return h+=g},c.decode64=function(a){a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var b,c,d,e,g="",h=0;h>4),64!==d&&(g+=String.fromCharCode((15&c)<<4|d>>2),64!==e&&(g+=String.fromCharCode((3&d)<<6|e)));return g},c.encodeUtf8=function(a){return unescape(encodeURIComponent(a))},c.decodeUtf8=function(a){return decodeURIComponent(escape(a))}},{}],15:[function(a,b){var c=a("./sha.js"),d=a("./forge_sha256.js");b.exports={md5:a("./md5.js"),sha1:c.sha1,sha224:c.sha224,sha256:c.sha256,sha384:c.sha384,sha512:c.sha512,ripemd:a("./ripe-md.js"),digest:function(a,b){switch(a){case 1:return this.md5(b);case 2:return this.sha1(b);case 3:return this.ripemd(b);case 8:var c=d.create();return c.update(b),c.digest().getBytes();case 9:return this.sha384(b);case 10:return this.sha512(b);case 11:return this.sha224(b);default:throw new Error("Invalid hash function.")}},getHashByteLength:function(a){switch(a){case 1:return 16;case 2:case 3:return 20;case 8:return 32;case 9:return 48;case 10:return 64;case 11:return 28;default:throw new Error("Invalid hash algorithm.")}}}},{"./forge_sha256.js":13,"./md5.js":16,"./ripe-md.js":17,"./sha.js":18}],16:[function(a,b){function c(a,b){var c=a[0],d=a[1],i=a[2],j=a[3];c=e(c,d,i,j,b[0],7,-680876936),j=e(j,c,d,i,b[1],12,-389564586),i=e(i,j,c,d,b[2],17,606105819),d=e(d,i,j,c,b[3],22,-1044525330),c=e(c,d,i,j,b[4],7,-176418897),j=e(j,c,d,i,b[5],12,1200080426),i=e(i,j,c,d,b[6],17,-1473231341),d=e(d,i,j,c,b[7],22,-45705983),c=e(c,d,i,j,b[8],7,1770035416),j=e(j,c,d,i,b[9],12,-1958414417),i=e(i,j,c,d,b[10],17,-42063),d=e(d,i,j,c,b[11],22,-1990404162),c=e(c,d,i,j,b[12],7,1804603682),j=e(j,c,d,i,b[13],12,-40341101),i=e(i,j,c,d,b[14],17,-1502002290),d=e(d,i,j,c,b[15],22,1236535329),c=f(c,d,i,j,b[1],5,-165796510),j=f(j,c,d,i,b[6],9,-1069501632),i=f(i,j,c,d,b[11],14,643717713),d=f(d,i,j,c,b[0],20,-373897302),c=f(c,d,i,j,b[5],5,-701558691),j=f(j,c,d,i,b[10],9,38016083),i=f(i,j,c,d,b[15],14,-660478335),d=f(d,i,j,c,b[4],20,-405537848),c=f(c,d,i,j,b[9],5,568446438),j=f(j,c,d,i,b[14],9,-1019803690),i=f(i,j,c,d,b[3],14,-187363961),d=f(d,i,j,c,b[8],20,1163531501),c=f(c,d,i,j,b[13],5,-1444681467),j=f(j,c,d,i,b[2],9,-51403784),i=f(i,j,c,d,b[7],14,1735328473),d=f(d,i,j,c,b[12],20,-1926607734),c=g(c,d,i,j,b[5],4,-378558),j=g(j,c,d,i,b[8],11,-2022574463),i=g(i,j,c,d,b[11],16,1839030562),d=g(d,i,j,c,b[14],23,-35309556),c=g(c,d,i,j,b[1],4,-1530992060),j=g(j,c,d,i,b[4],11,1272893353),i=g(i,j,c,d,b[7],16,-155497632),d=g(d,i,j,c,b[10],23,-1094730640),c=g(c,d,i,j,b[13],4,681279174),j=g(j,c,d,i,b[0],11,-358537222),i=g(i,j,c,d,b[3],16,-722521979),d=g(d,i,j,c,b[6],23,76029189),c=g(c,d,i,j,b[9],4,-640364487),j=g(j,c,d,i,b[12],11,-421815835),i=g(i,j,c,d,b[15],16,530742520),d=g(d,i,j,c,b[2],23,-995338651),c=h(c,d,i,j,b[0],6,-198630844),j=h(j,c,d,i,b[7],10,1126891415),i=h(i,j,c,d,b[14],15,-1416354905),d=h(d,i,j,c,b[5],21,-57434055),c=h(c,d,i,j,b[12],6,1700485571),j=h(j,c,d,i,b[3],10,-1894986606),i=h(i,j,c,d,b[10],15,-1051523),d=h(d,i,j,c,b[1],21,-2054922799),c=h(c,d,i,j,b[8],6,1873313359),j=h(j,c,d,i,b[15],10,-30611744),i=h(i,j,c,d,b[6],15,-1560198380),d=h(d,i,j,c,b[13],21,1309151649),c=h(c,d,i,j,b[4],6,-145523070),j=h(j,c,d,i,b[11],10,-1120210379),i=h(i,j,c,d,b[2],15,718787259),d=h(d,i,j,c,b[9],21,-343485551),a[0]=n(c,a[0]),a[1]=n(d,a[1]),a[2]=n(i,a[2]),a[3]=n(j,a[3])}function d(a,b,c,d,e,f){return b=n(n(b,a),n(d,f)),n(b<>>32-e,c)}function e(a,b,c,e,f,g,h){return d(b&c|~b&e,a,b,f,g,h)}function f(a,b,c,e,f,g,h){return d(b&e|c&~e,a,b,f,g,h)}function g(a,b,c,e,f,g,h){return d(b^c^e,a,b,f,g,h)}function h(a,b,c,e,f,g,h){return d(c^(b|~e),a,b,f,g,h)}function i(a){txt="";var b,d=a.length,e=[1732584193,-271733879,-1732584194,271733878];for(b=64;b<=a.length;b+=64)c(e,j(a.substring(b-64,b)));a=a.substring(b-64);var f=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(b=0;b>2]|=a.charCodeAt(b)<<(b%4<<3);if(f[b>>2]|=128<<(b%4<<3),b>55)for(c(e,f),b=0;16>b;b++)f[b]=0;return f[14]=8*d,c(e,f),e}function j(a){var b,c=[];for(b=0;64>b;b+=4)c[b>>2]=a.charCodeAt(b)+(a.charCodeAt(b+1)<<8)+(a.charCodeAt(b+2)<<16)+(a.charCodeAt(b+3)<<24);return c}function k(a){for(var b="",c=0;4>c;c++)b+=p[a>>8*c+4&15]+p[a>>8*c&15];return b}function l(a){for(var b=0;b>16)+(b>>16)+(c>>16);return d<<16|65535&c}var o=a("../../util.js");b.exports=function(a){var b=m(a),c=o.hex2bin(b);return c};var p="0123456789abcdef".split("");"5d41402abc4b2a76b9719d911017c592"!=m("hello")},{"../../util.js":61}],17:[function(a,b){function c(a,b){return new Number(a<>>32-b)}function d(a,b,c){return new Number(a^b^c)}function e(a,b,c){return new Number(a&b|~a&c)}function f(a,b,c){return new Number((a|~b)^c)}function g(a,b,c){return new Number(a&c|b&~c)}function h(a,b,c){return new Number(a^(b|~c))}function i(a,b,i,j,k,l,m,n){switch(n){case 0:a+=d(b,i,j)+l+0;break;case 1:a+=e(b,i,j)+l+1518500249;break;case 2:a+=f(b,i,j)+l+1859775393;break;case 3:a+=g(b,i,j)+l+2400959708;break;case 4:a+=h(b,i,j)+l+2840853838;break;case 5:a+=h(b,i,j)+l+1352829926;break;case 6:a+=g(b,i,j)+l+1548603684;break;case 7:a+=f(b,i,j)+l+1836072691;break;case 8:a+=e(b,i,j)+l+2053994217;break;case 9:a+=d(b,i,j)+l+0;break;default:throw new Error("Bogus round number")}a=c(a,m)+k,i=c(i,10),a&=4294967295,b&=4294967295,i&=4294967295,j&=4294967295,k&=4294967295;var o=[];return o[0]=a,o[1]=b,o[2]=i,o[3]=j,o[4]=k,o[5]=l,o[6]=m,o}function j(a){a[0]=1732584193,a[1]=4023233417,a[2]=2562383102,a[3]=271733878,a[4]=3285377520}function k(a,b){blockA=[],blockB=[];var c,d,e;for(d=0;5>d;d++)blockA[d]=new Number(a[d]),blockB[d]=new Number(a[d]);var f=0;for(e=0;5>e;e++)for(d=0;16>d;d++)c=i(blockA[(f+0)%5],blockA[(f+1)%5],blockA[(f+2)%5],blockA[(f+3)%5],blockA[(f+4)%5],b[s[e][d]],r[e][d],e),blockA[(f+0)%5]=c[0],blockA[(f+1)%5]=c[1],blockA[(f+2)%5]=c[2],blockA[(f+3)%5]=c[3],blockA[(f+4)%5]=c[4],f+=4;for(f=0,e=5;10>e;e++)for(d=0;16>d;d++)c=i(blockB[(f+0)%5],blockB[(f+1)%5],blockB[(f+2)%5],blockB[(f+3)%5],blockB[(f+4)%5],b[s[e][d]],r[e][d],e),blockB[(f+0)%5]=c[0],blockB[(f+1)%5]=c[1],blockB[(f+2)%5]=c[2],blockB[(f+3)%5]=c[3],blockB[(f+4)%5]=c[4],f+=4;blockB[3]+=blockA[2]+a[1],a[1]=a[2]+blockA[3]+blockB[4],a[2]=a[3]+blockA[4]+blockB[0],a[3]=a[4]+blockA[0]+blockB[1],a[4]=a[0]+blockA[1]+blockB[2],a[0]=blockB[3]}function l(a){for(var b=0;16>b;b++)a[b]=0}function m(a,b,c,d){var e=new Array(16);l(e);for(var f=0,g=0;(63&c)>g;g++)e[g>>>2]^=(255&b.charCodeAt(f++))<<8*(3&g);e[c>>>2&15]^=1<<8*(3&c)+7,(63&c)>55&&(k(a,e),e=new Array(16),l(e)),e[14]=c<<3,e[15]=c>>>29|d<<3,k(a,e)}function n(a){var b=(255&a.charCodeAt(3))<<24;return b|=(255&a.charCodeAt(2))<<16,b|=(255&a.charCodeAt(1))<<8,b|=255&a.charCodeAt(0)}function o(a){var b,c,d=new Array(q/32),e=new Array(q/8);j(d),b=a.length;var f=new Array(16);l(f);var g,h=0;for(c=b;c>63;c-=64){for(g=0;16>g;g++)f[g]=n(a.substr(h,4)),h+=4;k(d,f)}for(m(d,a.substr(h),b,0),g=0;q/8>g;g+=4)e[g]=255&d[g>>>2],e[g+1]=d[g>>>2]>>>8&255,e[g+2]=d[g>>>2]>>>16&255,e[g+3]=d[g>>>2]>>>24&255;return e}function p(a){for(var b=o(a),c="",d=0;q/8>d;d++)c+=String.fromCharCode(b[d]);return c}var q=160,r=[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12],[11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5],[11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12],[9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6],[9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11],[9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5],[15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8],[8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]],s=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8],[3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12],[1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2],[4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12],[6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2],[15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13],[8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14],[12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]];b.exports=p},{}],18:[function(a,b){var c=function(){var a=8,b="",c=0,d=function(a,b){this.highOrder=a,this.lowOrder=b},e=function(b){var c,d=[],e=(1<c;c+=a)d[c>>5]|=(b.charCodeAt(c/a)&e)<<32-a-c%32;return d},f=function(a){var b,c,d=[],e=a.length;for(b=0;e>b;b+=2){if(c=parseInt(a.substr(b,2),16),isNaN(c))throw new Error("INVALID HEX STRING");d[b>>3]|=c<<24-4*(b%8)}return d},g=function(a){var b,d,e=c?"0123456789ABCDEF":"0123456789abcdef",f="",g=4*a.length;for(b=0;g>b;b+=1)d=a[b>>2]>>8*(3-b%4),f+=e.charAt(d>>4&15)+e.charAt(15&d);return f},h=function(a){var c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",g="",h=4*a.length;for(c=0;h>c;c+=3)for(e=(a[c>>2]>>8*(3-c%4)&255)<<16|(a[c+1>>2]>>8*(3-(c+1)%4)&255)<<8|a[c+2>>2]>>8*(3-(c+2)%4)&255,d=0;4>d;d+=1)g+=8*c+6*d<=32*a.length?f.charAt(e>>6*(3-d)&63):b;return g},i=function(a){for(var b="",c=255,d=0;d<32*a.length;d+=8)b+=String.fromCharCode(a[d>>5]>>>24-d%32&c);return b},j=function(a,b){return a<>>32-b},k=function(a,b){return a>>>b|a<<32-b},l=function(a,b){return 32>=b?new d(a.highOrder>>>b|a.lowOrder<<32-b,a.lowOrder>>>b|a.highOrder<<32-b):new d(a.lowOrder>>>b|a.highOrder<<32-b,a.highOrder>>>b|a.lowOrder<<32-b)},m=function(a,b){return a>>>b},n=function(a,b){return 32>=b?new d(a.highOrder>>>b,a.lowOrder>>>b|a.highOrder<<32-b):new d(0,a.highOrder<<32-b)},o=function(a,b,c){return a^b^c},p=function(a,b,c){return a&b^~a&c},q=function(a,b,c){return new d(a.highOrder&b.highOrder^~a.highOrder&c.highOrder,a.lowOrder&b.lowOrder^~a.lowOrder&c.lowOrder)},r=function(a,b,c){return a&b^a&c^b&c},s=function(a,b,c){return new d(a.highOrder&b.highOrder^a.highOrder&c.highOrder^b.highOrder&c.highOrder,a.lowOrder&b.lowOrder^a.lowOrder&c.lowOrder^b.lowOrder&c.lowOrder)},t=function(a){return k(a,2)^k(a,13)^k(a,22)},u=function(a){var b=l(a,28),c=l(a,34),e=l(a,39);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},v=function(a){return k(a,6)^k(a,11)^k(a,25)},w=function(a){var b=l(a,14),c=l(a,18),e=l(a,41);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},x=function(a){return k(a,7)^k(a,18)^m(a,3)},y=function(a){var b=l(a,1),c=l(a,8),e=n(a,7);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},z=function(a){return k(a,17)^k(a,19)^m(a,10)},A=function(a){var b=l(a,19),c=l(a,61),e=n(a,6);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},B=function(a,b){var c=(65535&a)+(65535&b),d=(a>>>16)+(b>>>16)+(c>>>16);return(65535&d)<<16|65535&c -},C=function(a,b,c,d){var e=(65535&a)+(65535&b)+(65535&c)+(65535&d),f=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16);return(65535&f)<<16|65535&e},D=function(a,b,c,d,e){var f=(65535&a)+(65535&b)+(65535&c)+(65535&d)+(65535&e),g=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16)+(f>>>16);return(65535&g)<<16|65535&f},E=function(a,b){var c,e,f,g;return c=(65535&a.lowOrder)+(65535&b.lowOrder),e=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c>>>16),f=(65535&e)<<16|65535&c,c=(65535&a.highOrder)+(65535&b.highOrder)+(e>>>16),e=(a.highOrder>>>16)+(b.highOrder>>>16)+(c>>>16),g=(65535&e)<<16|65535&c,new d(g,f)},F=function(a,b,c,e){var f,g,h,i;return f=(65535&a.lowOrder)+(65535&b.lowOrder)+(65535&c.lowOrder)+(65535&e.lowOrder),g=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(e.lowOrder>>>16)+(f>>>16),h=(65535&g)<<16|65535&f,f=(65535&a.highOrder)+(65535&b.highOrder)+(65535&c.highOrder)+(65535&e.highOrder)+(g>>>16),g=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(e.highOrder>>>16)+(f>>>16),i=(65535&g)<<16|65535&f,new d(i,h)},G=function(a,b,c,e,f){var g,h,i,j;return g=(65535&a.lowOrder)+(65535&b.lowOrder)+(65535&c.lowOrder)+(65535&e.lowOrder)+(65535&f.lowOrder),h=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(e.lowOrder>>>16)+(f.lowOrder>>>16)+(g>>>16),i=(65535&h)<<16|65535&g,g=(65535&a.highOrder)+(65535&b.highOrder)+(65535&c.highOrder)+(65535&e.highOrder)+(65535&f.highOrder)+(h>>>16),h=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(e.highOrder>>>16)+(f.highOrder>>>16)+(g>>>16),j=(65535&h)<<16|65535&g,new d(j,i)},H=function(a,b){var c,d,e,f,g,h,i,k,l,m=[],n=p,q=o,s=r,t=j,u=B,v=D,w=[1732584193,4023233417,2562383102,271733878,3285377520],x=[1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782];for(a[b>>5]|=128<<24-b%32,a[(b+65>>9<<4)+15]=b,l=a.length,i=0;l>i;i+=16){for(c=w[0],d=w[1],e=w[2],f=w[3],g=w[4],k=0;80>k;k+=1)m[k]=16>k?a[k+i]:t(m[k-3]^m[k-8]^m[k-14]^m[k-16],1),h=20>k?v(t(c,5),n(d,e,f),g,x[k],m[k]):40>k?v(t(c,5),q(d,e,f),g,x[k],m[k]):60>k?v(t(c,5),s(d,e,f),g,x[k],m[k]):v(t(c,5),q(d,e,f),g,x[k],m[k]),g=f,f=e,e=t(d,30),d=c,c=h;w[0]=u(c,w[0]),w[1]=u(d,w[1]),w[2]=u(e,w[2]),w[3]=u(f,w[3]),w[4]=u(g,w[4])}return w},I=function(a,b,c){var e,f,g,h,i,j,k,l,m,n,o,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z=[];for("SHA-224"===c||"SHA-256"===c?(H=64,I=(b+65>>9<<4)+15,L=16,M=1,W=Number,N=B,O=C,P=D,Q=x,R=z,S=t,T=v,V=r,U=p,X=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],o="SHA-224"===c?[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]:[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]):("SHA-384"===c||"SHA-512"===c)&&(H=80,I=(b+128>>10<<5)+31,L=32,M=2,W=d,N=E,O=F,P=G,Q=y,R=A,S=u,T=w,V=s,U=q,X=[new W(1116352408,3609767458),new W(1899447441,602891725),new W(3049323471,3964484399),new W(3921009573,2173295548),new W(961987163,4081628472),new W(1508970993,3053834265),new W(2453635748,2937671579),new W(2870763221,3664609560),new W(3624381080,2734883394),new W(310598401,1164996542),new W(607225278,1323610764),new W(1426881987,3590304994),new W(1925078388,4068182383),new W(2162078206,991336113),new W(2614888103,633803317),new W(3248222580,3479774868),new W(3835390401,2666613458),new W(4022224774,944711139),new W(264347078,2341262773),new W(604807628,2007800933),new W(770255983,1495990901),new W(1249150122,1856431235),new W(1555081692,3175218132),new W(1996064986,2198950837),new W(2554220882,3999719339),new W(2821834349,766784016),new W(2952996808,2566594879),new W(3210313671,3203337956),new W(3336571891,1034457026),new W(3584528711,2466948901),new W(113926993,3758326383),new W(338241895,168717936),new W(666307205,1188179964),new W(773529912,1546045734),new W(1294757372,1522805485),new W(1396182291,2643833823),new W(1695183700,2343527390),new W(1986661051,1014477480),new W(2177026350,1206759142),new W(2456956037,344077627),new W(2730485921,1290863460),new W(2820302411,3158454273),new W(3259730800,3505952657),new W(3345764771,106217008),new W(3516065817,3606008344),new W(3600352804,1432725776),new W(4094571909,1467031594),new W(275423344,851169720),new W(430227734,3100823752),new W(506948616,1363258195),new W(659060556,3750685593),new W(883997877,3785050280),new W(958139571,3318307427),new W(1322822218,3812723403),new W(1537002063,2003034995),new W(1747873779,3602036899),new W(1955562222,1575990012),new W(2024104815,1125592928),new W(2227730452,2716904306),new W(2361852424,442776044),new W(2428436474,593698344),new W(2756734187,3733110249),new W(3204031479,2999351573),new W(3329325298,3815920427),new W(3391569614,3928383900),new W(3515267271,566280711),new W(3940187606,3454069534),new W(4118630271,4000239992),new W(116418474,1914138554),new W(174292421,2731055270),new W(289380356,3203993006),new W(460393269,320620315),new W(685471733,587496836),new W(852142971,1086792851),new W(1017036298,365543100),new W(1126000580,2618297676),new W(1288033470,3409855158),new W(1501505948,4234509866),new W(1607167915,987167468),new W(1816402316,1246189591)],o="SHA-384"===c?[new W(3418070365,3238371032),new W(1654270250,914150663),new W(2438529370,812702999),new W(355462360,4144912697),new W(1731405415,4290775857),new W(41048885895,1750603025),new W(3675008525,1694076839),new W(1203062813,3204075428)]:[new W(1779033703,4089235720),new W(3144134277,2227873595),new W(1013904242,4271175723),new W(2773480762,1595750129),new W(1359893119,2917565137),new W(2600822924,725511199),new W(528734635,4215389547),new W(1541459225,327033209)]),a[b>>5]|=128<<24-b%32,a[I]=b,Y=a.length,J=0;Y>J;J+=L){for(e=o[0],f=o[1],g=o[2],h=o[3],i=o[4],j=o[5],k=o[6],l=o[7],K=0;H>K;K+=1)Z[K]=16>K?new W(a[K*M+J],a[K*M+J+1]):O(R(Z[K-2]),Z[K-7],Q(Z[K-15]),Z[K-16]),m=P(l,T(i),U(i,j,k),X[K],Z[K]),n=N(S(e),V(e,f,g)),l=k,k=j,j=i,i=N(h,m),h=g,g=f,f=e,e=N(m,n);o[0]=N(e,o[0]),o[1]=N(f,o[1]),o[2]=N(g,o[2]),o[3]=N(h,o[3]),o[4]=N(i,o[4]),o[5]=N(j,o[5]),o[6]=N(k,o[6]),o[7]=N(l,o[7])}switch(c){case"SHA-224":return[o[0],o[1],o[2],o[3],o[4],o[5],o[6]];case"SHA-256":return o;case"SHA-384":return[o[0].highOrder,o[0].lowOrder,o[1].highOrder,o[1].lowOrder,o[2].highOrder,o[2].lowOrder,o[3].highOrder,o[3].lowOrder,o[4].highOrder,o[4].lowOrder,o[5].highOrder,o[5].lowOrder];case"SHA-512":return[o[0].highOrder,o[0].lowOrder,o[1].highOrder,o[1].lowOrder,o[2].highOrder,o[2].lowOrder,o[3].highOrder,o[3].lowOrder,o[4].highOrder,o[4].lowOrder,o[5].highOrder,o[5].lowOrder,o[6].highOrder,o[6].lowOrder,o[7].highOrder,o[7].lowOrder];default:throw new Error("Unknown SHA variant")}},J=function(b,c){if(this.sha1=null,this.sha224=null,this.sha256=null,this.sha384=null,this.sha512=null,this.strBinLen=null,this.strToHash=null,"HEX"===c){if(0!==b.length%2)throw new Error("TEXT MUST BE IN BYTE INCREMENTS");this.strBinLen=4*b.length,this.strToHash=f(b)}else{if("ASCII"!==c&&"undefined"!=typeof c)throw new Error("UNKNOWN TEXT INPUT TYPE");this.strBinLen=b.length*a,this.strToHash=e(b)}};return J.prototype={getHash:function(a,b){var c=null,d=this.strToHash.slice();switch(b){case"HEX":c=g;break;case"B64":c=h;break;case"ASCII":c=i;break;default:throw new Error("FORMAT NOT RECOGNIZED")}switch(a){case"SHA-1":return null===this.sha1&&(this.sha1=H(d,this.strBinLen)),c(this.sha1);case"SHA-224":return null===this.sha224&&(this.sha224=I(d,this.strBinLen,a)),c(this.sha224);case"SHA-256":return null===this.sha256&&(this.sha256=I(d,this.strBinLen,a)),c(this.sha256);case"SHA-384":return null===this.sha384&&(this.sha384=I(d,this.strBinLen,a)),c(this.sha384);case"SHA-512":return null===this.sha512&&(this.sha512=I(d,this.strBinLen,a)),c(this.sha512);default:throw new Error("HASH NOT RECOGNIZED")}},getHMAC:function(b,c,d,j){var k,l,m,n,o,p,q,r,s,t=[],u=[];switch(j){case"HEX":k=g;break;case"B64":k=h;break;case"ASCII":k=i;break;default:throw new Error("FORMAT NOT RECOGNIZED")}switch(d){case"SHA-1":m=64,s=160;break;case"SHA-224":m=64,s=224;break;case"SHA-256":m=64,s=256;break;case"SHA-384":m=128,s=384;break;case"SHA-512":m=128,s=512;break;default:throw new Error("HASH NOT RECOGNIZED")}if("HEX"===c){if(0!==b.length%2)throw new Error("KEY MUST BE IN BYTE INCREMENTS");l=f(b),r=4*b.length}else{if("ASCII"!==c)throw new Error("UNKNOWN KEY INPUT TYPE");l=e(b),r=b.length*a}for(n=8*m,q=m/4-1,r/8>m?(l="SHA-1"===d?H(l,r):I(l,r,d),l[q]&=4294967040):m>r/8&&(l[q]&=4294967040),o=0;q>=o;o+=1)t[o]=909522486^l[o],u[o]=1549556828^l[o];return"SHA-1"===d?(p=H(t.concat(this.strToHash),n+this.strBinLen),p=H(u.concat(p),n+s)):(p=I(t.concat(this.strToHash),n+this.strBinLen,d),p=I(u.concat(p),n+s,d)),k(p)}},J}();b.exports={sha1:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-1","ASCII")},sha224:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-224","ASCII")},sha256:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-256","ASCII")},sha384:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-384","ASCII")},sha512:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-512","ASCII")}}},{}],19:[function(a,b){b.exports={cipher:a("./cipher"),hash:a("./hash"),cfb:a("./cfb.js"),publicKey:a("./public_key"),signature:a("./signature.js"),random:a("./random.js"),pkcs1:a("./pkcs1.js")};var c=a("./crypto.js");for(var d in c)b.exports[d]=c[d]},{"./cfb.js":5,"./cipher":10,"./crypto.js":12,"./hash":15,"./pkcs1.js":20,"./public_key":23,"./random.js":26,"./signature.js":27}],20:[function(a,b){function c(a){for(var b,c="";c.lengthb-11)throw new Error("Message too long");var e=c(b-d-3),f=String.fromCharCode(0)+String.fromCharCode(2)+e+String.fromCharCode(0)+a;return f},decode:function(a){0!==a.charCodeAt(0)&&(a=String.fromCharCode(0)+a);for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=2;0!==a.charCodeAt(d)&&d=8&&0===f)return a.substr(d);throw new Error("Decryption error")}},emsa:{encode:function(a,b,c){var e,i=h.digest(a,b);if(i.length!==h.getHashByteLength(a))throw new Error("Invalid hash length");var j="";for(e=0;ec)throw new Error("Intended encoded message length too short");var l="";for(e=0;c-k-3>e;e++)l+=String.fromCharCode(255);var m=String.fromCharCode(0)+String.fromCharCode(1)+l+String.fromCharCode(0)+j;return new g(f.hexstrdump(m),16)}}}},{"../util.js":61,"./crypto.js":12,"./hash":15,"./public_key/jsbn.js":24,"./random.js":26}],21:[function(a,b){function c(){function a(a,b,c,h,i,j){for(var k,l,m,n=g.getLeftNBits(f.digest(a,b),i.bitLength()),o=new d(g.hexstrdump(n),16);;)if(k=e.getRandomBigIntegerInRange(d.ONE,i.subtract(d.ONE)),l=c.modPow(k,h).mod(i),m=k.modInverse(i).multiply(o.add(j.multiply(l))).mod(i),0!=l&&0!=m)break;var p=[];return p[0]=l.toMPI(),p[1]=m.toMPI(),p}function b(a){var b=h.prefer_hash_algorithm;switch(Math.round(a.bitLength()/8)){case 20:return 2!=b&&b>11&&10!=b&&8>b?2:b;case 28:return b>11&&8>b?11:b;case 32:return b>10&&8>b?8:b;default:return g.print_debug("DSA select hash algorithm: returning null for an unknown length of q"),null}}function c(a,b,c,e,h,i,j,k){var l=g.getLeftNBits(f.digest(a,e),i.bitLength()),m=new d(g.hexstrdump(l),16);if(d.ZERO.compareTo(b)>0||b.compareTo(i)>0||d.ZERO.compareTo(c)>0||c.compareTo(i)>0)return g.print_debug("invalid DSA Signature"),null;var n=c.modInverse(i),o=m.multiply(n).mod(i),p=b.multiply(n).mod(i);return j.modPow(o,h).multiply(k.modPow(p,h)).mod(h).mod(i)}this.select_hash_algorithm=b,this.sign=a,this.verify=c}var d=a("./jsbn.js"),e=a("../random.js"),f=a("../hash"),g=a("../../util.js"),h=a("../../config");b.exports=c},{"../../config":4,"../../util.js":61,"../hash":15,"../random.js":26,"./jsbn.js":24}],22:[function(a,b){function c(){function a(a,b,c,f){var g=c.subtract(d.TWO),h=e.getRandomBigIntegerInRange(d.ONE,g);h=h.mod(g).add(d.ONE);var i=[];return i[0]=b.modPow(h,c),i[1]=f.modPow(h,c).multiply(a).mod(c),i}function b(a,b,c,d){return f.print_debug("Elgamal Decrypt:\nc1:"+f.hexstrdump(a.toMPI())+"\nc2:"+f.hexstrdump(b.toMPI())+"\np:"+f.hexstrdump(c.toMPI())+"\nx:"+f.hexstrdump(d.toMPI())),a.modPow(d,c).modInverse(c).multiply(b).mod(c)}this.encrypt=a,this.decrypt=b}var d=a("./jsbn.js"),e=a("../random.js"),f=a("../../util.js");b.exports=c},{"../../util.js":61,"../random.js":26,"./jsbn.js":24}],23:[function(a,b){b.exports={rsa:a("./rsa.js"),elgamal:a("./elgamal.js"),dsa:a("./dsa.js")}},{"./dsa.js":21,"./elgamal.js":22,"./rsa.js":25}],24:[function(a,b){function c(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function d(){return new c(null)}function e(a,b,c,d,e,f){for(;--f>=0;){var g=b*this[a++]+c[d]+e;e=Math.floor(g/67108864),c[d++]=67108863&g}return e}function f(a){return ec.charAt(a)}function g(a,b){var c=fc[a.charCodeAt(b)];return null==c?-1:c}function h(a){for(var b=this.t-1;b>=0;--b)a[b]=this[b];a.t=this.t,a.s=this.s}function i(a){this.t=1,this.s=0>a?-1:0,a>0?this[0]=a:-1>a?this[0]=a+this.DV:this.t=0}function j(a){var b=d();return b.fromInt(a),b}function k(a,b){var d;if(16==b)d=4;else if(8==b)d=3;else if(256==b)d=8;else if(2==b)d=1;else if(32==b)d=5;else{if(4!=b)return void this.fromRadix(a,b);d=2}this.t=0,this.s=0;for(var e=a.length,f=!1,h=0;--e>=0;){var i=8==d?255&a[e]:g(a,e);0>i?"-"==a.charAt(e)&&(f=!0):(f=!1,0==h?this[this.t++]=i:h+d>this.DB?(this[this.t-1]|=(i&(1<>this.DB-h):this[this.t-1]|=i<=this.DB&&(h-=this.DB))}8==d&&0!=(128&a[0])&&(this.s=-1,h>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==a;)--this.t}function m(a){if(this.s<0)return"-"+this.negate().toString(a);var b;if(16==a)b=4;else if(8==a)b=3;else if(2==a)b=1;else if(32==a)b=5;else{if(4!=a)return this.toRadix(a);b=2}var c,d=(1<0)for(i>i)>0&&(e=!0,g=f(c));h>=0;)b>i?(c=(this[h]&(1<>(i+=this.DB-b)):(c=this[h]>>(i-=b)&d,0>=i&&(i+=this.DB,--h)),c>0&&(e=!0),e&&(g+=f(c));return e?g:"0"}function n(){var a=d();return c.ZERO.subTo(this,a),a}function o(){return this.s<0?this.negate():this}function p(a){var b=this.s-a.s;if(0!=b)return b;var c=this.t;if(b=c-a.t,0!=b)return this.s<0?-b:b;for(;--c>=0;)if(0!=(b=this[c]-a[c]))return b;return 0}function q(a){var b,c=1;return 0!=(b=a>>>16)&&(a=b,c+=16),0!=(b=a>>8)&&(a=b,c+=8),0!=(b=a>>4)&&(a=b,c+=4),0!=(b=a>>2)&&(a=b,c+=2),0!=(b=a>>1)&&(a=b,c+=1),c}function r(){return this.t<=0?0:this.DB*(this.t-1)+q(this[this.t-1]^this.s&this.DM)}function s(a,b){var c;for(c=this.t-1;c>=0;--c)b[c+a]=this[c];for(c=a-1;c>=0;--c)b[c]=0;b.t=this.t+a,b.s=this.s}function t(a,b){for(var c=a;c=0;--c)b[c+g+1]=this[c]>>e|h,h=(this[c]&f)<=0;--c)b[c]=0;b[g]=h,b.t=this.t+g+1,b.s=this.s,b.clamp()}function v(a,b){b.s=this.s;var c=Math.floor(a/this.DB);if(c>=this.t)return void(b.t=0);var d=a%this.DB,e=this.DB-d,f=(1<>d;for(var g=c+1;g>d;d>0&&(b[this.t-c-1]|=(this.s&f)<c;)d+=this[c]-a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d-=a.s}b.s=0>d?-1:0,-1>d?b[c++]=this.DV+d:d>0&&(b[c++]=d),b.t=c,b.clamp()}function x(a,b){var d=this.abs(),e=a.abs(),f=d.t;for(b.t=f+e.t;--f>=0;)b[f]=0;for(f=0;f=0;)a[c]=0;for(c=0;c=b.DV&&(a[c+b.t]-=b.DV,a[c+b.t+1]=1)}a.t>0&&(a[a.t-1]+=b.am(c,b[c],a,2*c,0,1)),a.s=0,a.clamp()}function z(a,b,e){var f=a.abs();if(!(f.t<=0)){var g=this.abs();if(g.t0?(f.lShiftTo(k,h),g.lShiftTo(k,e)):(f.copyTo(h),g.copyTo(e));var l=h.t,m=h[l-1];if(0!=m){var n=m*(1<1?h[l-2]>>this.F2:0),o=this.FV/n,p=(1<=0&&(e[e.t++]=1,e.subTo(u,e)),c.ONE.dlShiftTo(l,u),u.subTo(h,h);h.t=0;){var v=e[--s]==m?this.DM:Math.floor(e[s]*o+(e[s-1]+r)*p);if((e[s]+=h.am(0,v,e,t,0,l))0&&e.rShiftTo(k,e),0>i&&c.ZERO.subTo(e,e)}}}function A(a){var b=d();return this.abs().divRemTo(a,null,b),this.s<0&&b.compareTo(c.ZERO)>0&&a.subTo(b,b),b}function B(a){this.m=a}function C(a){return a.s<0||a.compareTo(this.m)>=0?a.mod(this.m):a}function D(a){return a}function E(a){a.divRemTo(this.m,null,a)}function F(a,b,c){a.multiplyTo(b,c),this.reduce(c)}function G(a,b){a.squareTo(b),this.reduce(b)}function H(){if(this.t<1)return 0;var a=this[0];if(0==(1&a))return 0;var b=3&a;return b=b*(2-(15&a)*b)&15,b=b*(2-(255&a)*b)&255,b=b*(2-((65535&a)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV,b>0?this.DV-b:-b}function I(a){this.m=a,this.mp=a.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(b,b),b}function K(a){var b=d();return a.copyTo(b),this.reduce(b),b}function L(a){for(;a.t<=this.mt2;)a[a.t++]=0;for(var b=0;b>15)*this.mpl&this.um)<<15)&a.DM;for(c=b+this.m.t,a[c]+=this.m.am(0,d,a,b,0,this.m.t);a[c]>=a.DV;)a[c]-=a.DV,a[++c]++}a.clamp(),a.drShiftTo(this.m.t,a),a.compareTo(this.m)>=0&&a.subTo(this.m,a)}function M(a,b){a.squareTo(b),this.reduce(b)}function N(a,b,c){a.multiplyTo(b,c),this.reduce(c)}function O(){return 0==(this.t>0?1&this[0]:this.s)}function P(a,b){if(a>4294967295||1>a)return c.ONE;var e=d(),f=d(),g=b.convert(this),h=q(a)-1;for(g.copyTo(e);--h>=0;)if(b.sqrTo(e,f),(a&1<0)b.mulTo(f,g,e);else{var i=e;e=f,f=i}return b.revert(e)}function Q(a,b){var c;return c=256>a||b.isEven()?new B(b):new I(b),this.exp(a,c)}function R(){var a=d();return this.copyTo(a),a}function S(){if(this.s<0){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<>24}function U(){return 0==this.t?this.s:this[0]<<16>>16}function V(a){return Math.floor(Math.LN2*this.DB/Math.log(a))}function W(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1}function X(a){if(null==a&&(a=10),0==this.signum()||2>a||a>36)return"0";var b=this.chunkSize(a),c=Math.pow(a,b),e=j(c),f=d(),g=d(),h="";for(this.divRemTo(e,f,g);f.signum()>0;)h=(c+g.intValue()).toString(a).substr(1)+h,f.divRemTo(e,f,g);return g.intValue().toString(a)+h}function Y(a,b){this.fromInt(0),null==b&&(b=10);for(var d=this.chunkSize(b),e=Math.pow(b,d),f=!1,h=0,i=0,j=0;jk?"-"==a.charAt(j)&&0==this.signum()&&(f=!0):(i=b*i+k,++h>=d&&(this.dMultiply(e),this.dAddOffset(i,0),h=0,i=0))}h>0&&(this.dMultiply(Math.pow(b,h)),this.dAddOffset(i,0)),f&&c.ZERO.subTo(this,this)}function Z(a,b,d){if("number"==typeof b)if(2>a)this.fromInt(1);else for(this.fromNumber(a,d),this.testBit(a-1)||this.bitwiseTo(c.ONE.shiftLeft(a-1),fb,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(c.ONE.shiftLeft(a-1),this);else{var e=new Array,f=7&a;e.length=(a>>3)+1,b.nextBytes(e),f>0?e[0]&=(1<0)for(d>d)!=(this.s&this.DM)>>d&&(b[e++]=c|this.s<=0;)8>d?(c=(this[a]&(1<>(d+=this.DB-8)):(c=this[a]>>(d-=8)&255,0>=d&&(d+=this.DB,--a)),(e>0||c!=this.s)&&(b[e++]=c);return b}function _(a){return 0==this.compareTo(a)}function ab(a){return this.compareTo(a)<0?this:a}function bb(a){return this.compareTo(a)>0?this:a}function cb(a,b,c){var d,e,f=Math.min(a.t,this.t);for(d=0;f>d;++d)c[d]=b(this[d],a[d]);if(a.ta?this.rShiftTo(-a,b):this.lShiftTo(a,b),b}function nb(a){var b=d();return 0>a?this.lShiftTo(-a,b):this.rShiftTo(a,b),b}function ob(a){if(0==a)return-1;var b=0;return 0==(65535&a)&&(a>>=16,b+=16),0==(255&a)&&(a>>=8,b+=8),0==(15&a)&&(a>>=4,b+=4),0==(3&a)&&(a>>=2,b+=2),0==(1&a)&&++b,b}function pb(){for(var a=0;a=this.t?0!=this.s:0!=(this[b]&1<c;)d+=this[c]+a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d+=a.s}b.s=0>d?-1:0,d>0?b[c++]=d:-1>d&&(b[c++]=this.DV+d),b.t=c,b.clamp()}function yb(a){var b=d();return this.addTo(a,b),b}function zb(a){var b=d();return this.subTo(a,b),b}function Ab(a){var b=d();return this.multiplyTo(a,b),b}function Bb(){var a=d();return this.squareTo(a),a}function Cb(a){var b=d();return this.divRemTo(a,b,null),b}function Db(a){var b=d();return this.divRemTo(a,null,b),b}function Eb(a){var b=d(),c=d();return this.divRemTo(a,b,c),new Array(b,c)}function Fb(a){this[this.t]=this.am(0,a-1,this,0,0,this.t),++this.t,this.clamp()}function Gb(a,b){if(0!=a){for(;this.t<=b;)this[this.t++]=0;for(this[b]+=a;this[b]>=this.DV;)this[b]-=this.DV,++b>=this.t&&(this[this.t++]=0),++this[b]}}function Hb(){}function Ib(a){return a}function Jb(a,b,c){a.multiplyTo(b,c)}function Kb(a,b){a.squareTo(b)}function Lb(a){return this.exp(a,new Hb)}function Mb(a,b,c){var d=Math.min(this.t+a.t,b);for(c.s=0,c.t=d;d>0;)c[--d]=0;var e;for(e=c.t-this.t;e>d;++d)c[d+this.t]=this.am(0,a[d],c,d,0,this.t);for(e=Math.min(a.t,b);e>d;++d)this.am(0,a[d],c,d,0,b-d);c.clamp()}function Nb(a,b,c){--b;var d=c.t=this.t+a.t-b;for(c.s=0;--d>=0;)c[d]=0;for(d=Math.max(b-this.t,0);d2*this.m.t)return a.mod(this.m);if(a.compareTo(this.m)<0)return a;var b=d();return a.copyTo(b),this.reduce(b),b}function Qb(a){return a}function Rb(a){for(a.drShiftTo(this.m.t-1,this.r2),a.t>this.m.t+1&&(a.t=this.m.t+1,a.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);a.compareTo(this.r2)<0;)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);a.compareTo(this.m)>=0;)a.subTo(this.m,a)}function Sb(a,b){a.squareTo(b),this.reduce(b)}function Tb(a,b,c){a.multiplyTo(b,c),this.reduce(c)}function Ub(a,b){var c,e,f=a.bitLength(),g=j(1);if(0>=f)return g;c=18>f?1:48>f?3:144>f?4:768>f?5:6,e=8>f?new B(b):b.isEven()?new Ob(b):new I(b);var h=new Array,i=3,k=c-1,l=(1<1){var m=d();for(e.sqrTo(h[1],m);l>=i;)h[i]=d(),e.mulTo(m,h[i-2],h[i]),i+=2}var n,o,p=a.t-1,r=!0,s=d();for(f=q(a[p])-1;p>=0;){for(f>=k?n=a[p]>>f-k&l:(n=(a[p]&(1<0&&(n|=a[p-1]>>this.DB+f-k)),i=c;0==(1&n);)n>>=1,--i;if((f-=i)<0&&(f+=this.DB,--p),r)h[n].copyTo(g),r=!1;else{for(;i>1;)e.sqrTo(g,s),e.sqrTo(s,g),i-=2;i>0?e.sqrTo(g,s):(o=g,g=s,s=o),e.mulTo(s,h[n],g)}for(;p>=0&&0==(a[p]&1<f)return b;for(f>e&&(f=e),f>0&&(b.rShiftTo(f,b),c.rShiftTo(f,c));b.signum()>0;)(e=b.getLowestSetBit())>0&&b.rShiftTo(e,b),(e=c.getLowestSetBit())>0&&c.rShiftTo(e,c),b.compareTo(c)>=0?(b.subTo(c,b),b.rShiftTo(1,b)):(c.subTo(b,c),c.rShiftTo(1,c));return f>0&&c.lShiftTo(f,c),c}function Wb(a){if(0>=a)return 0;var b=this.DV%a,c=this.s<0?a-1:0;if(this.t>0)if(0==b)c=this[0]%a;else for(var d=this.t-1;d>=0;--d)c=(b*c+this[d])%a;return c}function Xb(a){var b=a.isEven();if(this.isEven()&&b||0==a.signum())return c.ZERO;for(var d=a.clone(),e=this.clone(),f=j(1),g=j(0),h=j(0),i=j(1);0!=d.signum();){for(;d.isEven();)d.rShiftTo(1,d),b?(f.isEven()&&g.isEven()||(f.addTo(this,f),g.subTo(a,g)),f.rShiftTo(1,f)):g.isEven()||g.subTo(a,g),g.rShiftTo(1,g);for(;e.isEven();)e.rShiftTo(1,e),b?(h.isEven()&&i.isEven()||(h.addTo(this,h),i.subTo(a,i)),h.rShiftTo(1,h)):i.isEven()||i.subTo(a,i),i.rShiftTo(1,i);d.compareTo(e)>=0?(d.subTo(e,d),b&&f.subTo(h,f),g.subTo(i,g)):(e.subTo(d,e),b&&h.subTo(f,h),i.subTo(g,i))}return 0!=e.compareTo(c.ONE)?c.ZERO:i.compareTo(a)>=0?i.subtract(a):i.signum()<0?(i.addTo(a,i),i.signum()<0?i.add(a):i):i}function Yb(a){var b,c=this.abs();if(1==c.t&&c[0]<=gc[gc.length-1]){for(b=0;bd;)d*=gc[e++];for(d=c.modInt(d);e>b;)if(d%gc[b++]==0)return!1}return c.millerRabin(a)}function q(a){var b,c=1;return 0!=(b=a>>>16)&&(a=b,c+=16),0!=(b=a>>8)&&(a=b,c+=8),0!=(b=a>>4)&&(a=b,c+=4),0!=(b=a>>2)&&(a=b,c+=2),0!=(b=a>>1)&&(a=b,c+=1),c}function Zb(){var a=this.toByteArray(),b=8*(a.length-1)+q(a[0]),c="";return c+=String.fromCharCode((65280&b)>>8),c+=String.fromCharCode(255&b),c+=ac.bin2str(a)}function $b(a){var b=this.subtract(c.ONE),e=b.getLowestSetBit();if(0>=e)return!1;var f=b.shiftRight(e);a=a+1>>1,a>gc.length&&(a=gc.length);for(var g,h=d(),i=[],j=0;a>j;++j){for(;g=gc[Math.floor(Math.random()*gc.length)],-1!=i.indexOf(g););i.push(g),h.fromInt(g);var k=h.modPow(f,this);if(0!=k.compareTo(c.ONE)&&0!=k.compareTo(b)){for(var g=1;g++=dc;++dc)fc[cc++]=dc;for(cc="a".charCodeAt(0),dc=10;36>dc;++dc)fc[cc++]=dc;for(cc="A".charCodeAt(0),dc=10;36>dc;++dc)fc[cc++]=dc;B.prototype.convert=C,B.prototype.revert=D,B.prototype.reduce=E,B.prototype.mulTo=F,B.prototype.sqrTo=G,I.prototype.convert=J,I.prototype.revert=K,I.prototype.reduce=L,I.prototype.mulTo=N,I.prototype.sqrTo=M,c.prototype.copyTo=h,c.prototype.fromInt=i,c.prototype.fromString=k,c.prototype.clamp=l,c.prototype.dlShiftTo=s,c.prototype.drShiftTo=t,c.prototype.lShiftTo=u,c.prototype.rShiftTo=v,c.prototype.subTo=w,c.prototype.multiplyTo=x,c.prototype.squareTo=y,c.prototype.divRemTo=z,c.prototype.invDigit=H,c.prototype.isEven=O,c.prototype.exp=P,c.prototype.toString=m,c.prototype.negate=n,c.prototype.abs=o,c.prototype.compareTo=p,c.prototype.bitLength=r,c.prototype.mod=A,c.prototype.modPowInt=Q,c.ZERO=j(0),c.ONE=j(1),c.TWO=j(2),b.exports=c,Hb.prototype.convert=Ib,Hb.prototype.revert=Ib,Hb.prototype.mulTo=Jb,Hb.prototype.sqrTo=Kb,Ob.prototype.convert=Pb,Ob.prototype.revert=Qb,Ob.prototype.reduce=Rb,Ob.prototype.mulTo=Tb,Ob.prototype.sqrTo=Sb;var gc=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],hc=(1<<26)/gc[gc.length-1],c=a("./jsbn.js");c.prototype.chunkSize=V,c.prototype.toRadix=X,c.prototype.fromRadix=Y,c.prototype.fromNumber=Z,c.prototype.bitwiseTo=cb,c.prototype.changeBit=tb,c.prototype.addTo=xb,c.prototype.dMultiply=Fb,c.prototype.dAddOffset=Gb,c.prototype.multiplyLowerTo=Mb,c.prototype.multiplyUpperTo=Nb,c.prototype.modInt=Wb,c.prototype.millerRabin=$b,c.prototype.clone=R,c.prototype.intValue=S,c.prototype.byteValue=T,c.prototype.shortValue=U,c.prototype.signum=W,c.prototype.toByteArray=$,c.prototype.equals=_,c.prototype.min=ab,c.prototype.max=bb,c.prototype.and=eb,c.prototype.or=gb,c.prototype.xor=ib,c.prototype.andNot=kb,c.prototype.not=lb,c.prototype.shiftLeft=mb,c.prototype.shiftRight=nb,c.prototype.getLowestSetBit=pb,c.prototype.bitCount=rb,c.prototype.testBit=sb,c.prototype.setBit=ub,c.prototype.clearBit=vb,c.prototype.flipBit=wb,c.prototype.add=yb,c.prototype.subtract=zb,c.prototype.multiply=Ab,c.prototype.divide=Cb,c.prototype.remainder=Db,c.prototype.divideAndRemainder=Eb,c.prototype.modPow=Ub,c.prototype.modInverse=Xb,c.prototype.pow=Lb,c.prototype.gcd=Vb,c.prototype.isProbablePrime=Yb,c.prototype.toMPI=Zb,c.prototype.square=Bb -},{"../../util.js":61,"./jsbn.js":24}],25:[function(a,b){function c(){function a(a){for(var b=0;b>1;for(d.e=parseInt(b,16),d.ee=new g(b,16);;){for(;d.p=new g(a-f,1,e),0!==d.p.subtract(g.ONE).gcd(d.ee).compareTo(g.ONE)||!d.p.isProbablePrime(10););for(;d.q=new g(f,1,e),0!==d.q.subtract(g.ONE).gcd(d.ee).compareTo(g.ONE)||!d.q.isProbablePrime(10););if(d.p.compareTo(d.q)<=0){var h=d.p;d.p=d.q,d.q=h}var i=d.p.subtract(g.ONE),j=d.q.subtract(g.ONE),l=i.multiply(j);if(0===l.gcd(d.ee).compareTo(g.ONE)){d.n=d.p.multiply(d.q),d.d=d.ee.modInverse(l),d.dmp1=d.d.mod(i),d.dmq1=d.d.mod(j),d.u=d.p.modInverse(d.q);break}}return d}this.encrypt=b,this.decrypt=a,this.verify=i,this.sign=f,this.generate=l,this.keyObject=k}var g=a("./jsbn.js"),h=a("../../util.js"),i=a("../random.js"),j=a("../../config"),k=g.ZERO,l=g.ZERO;b.exports=f},{"../../config":4,"../../util.js":61,"../random.js":26,"./jsbn.js":24}],26:[function(a,b){function c(){this.buffer=null,this.size=null}var d=a("../type/mpi.js"),e=null;"undefined"==typeof window&&(e=a("crypto")),b.exports={getRandomBytes:function(a){for(var b="",c=0;a>c;c++)b+=String.fromCharCode(this.getSecureRandomOctet());return b},getSecureRandom:function(a,b){for(var c=this.getSecureRandomUint(),d=(b-a).toString(2).length;(c&Math.pow(2,d)-1)>b-a;)c=this.getSecureRandomUint();return a+Math.abs(c&Math.pow(2,d)-1)},getSecureRandomOctet:function(){var a=new Uint8Array(1);return this.getRandomValues(a),a[0]},getSecureRandomUint:function(){var a=new Uint8Array(4),b=new DataView(a.buffer);return this.getRandomValues(a),b.getUint32(0)},getRandomValues:function(a){if(!(a instanceof Uint8Array))throw new Error("Invalid type: buf not an Uint8Array");if("undefined"!=typeof window&&window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(a);else if("undefined"!=typeof window&&"object"==typeof window.msCrypto&&"function"==typeof window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(a);else if(e){var b=e.randomBytes(a.length);a.set(b)}else{if(!this.randomBuffer.buffer)throw new Error("No secure random number generator available.");this.randomBuffer.get(a)}},getRandomBigInteger:function(a){if(1>a)throw new Error("Illegal parameter value: bits < 1");var b=Math.floor((a+7)/8),c=this.getRandomBytes(b);a%8>0&&(c=String.fromCharCode(Math.pow(2,a%8)-1&c.charCodeAt(0))+c.substring(1));var e=new d;return e.fromBytes(c),e.toBigInteger()},getRandomBigIntegerInRange:function(a,b){if(b.compareTo(a)<=0)throw new Error("Illegal parameter value: max <= min");for(var c=b.subtract(a),d=this.getRandomBigInteger(c.bitLength());d>c;)d=this.getRandomBigInteger(c.bitLength());return a.add(d)},randomBuffer:new c},c.prototype.init=function(a){this.buffer=new Uint8Array(a),this.size=0},c.prototype.set=function(a){if(!this.buffer)throw new Error("RandomBuffer is not initialized");if(!(a instanceof Uint8Array))throw new Error("Invalid type: buf not an Uint8Array");var b=this.buffer.length-this.size;a.length>b&&(a=a.subarray(0,b)),this.buffer.set(a,this.size),this.size+=a.length},c.prototype.get=function(a){if(!this.buffer)throw new Error("RandomBuffer is not initialized");if(!(a instanceof Uint8Array))throw new Error("Invalid type: buf not an Uint8Array");if(this.size>16)+String.fromCharCode(b>>8&255)+String.fromCharCode(255&b);return m.encode(c)}function f(a,b){var c=e(a),d=b;return c[0]==d[0]&&c[1]==d[1]&&c[2]==d[2]&&c[3]==d[3]}function g(a){for(var b=11994318,c=0;a.length-c>16;)b=b<<8^p[255&(b>>16^a.charCodeAt(c))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+1))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+2))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+3))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+4))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+5))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+6))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+7))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+8))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+9))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+10))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+11))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+12))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+13))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+14))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+15))],c+=16;for(var d=c;d>16^a.charCodeAt(c++))];return 16777215&b}function h(a){var b=/^\s*\n/m,c="",d=a,e=b.exec(a);if(null===e)throw new Error("Mandatory blank line missing between armor headers and armor data");return c=a.slice(0,e.index),d=a.slice(e.index+e[0].length),c=c.split("\n"),c.pop(),{headers:c,body:d}}function i(a){for(var b=0;bd;d++)c=a.charCodeAt(d),0===h?(f+=e.charAt(c>>2&63),b=(3&c)<<4):1==h?(f+=e.charAt(b|c>>4&15),b=(15&c)<<2):2==h&&(f+=e.charAt(b|c>>6&3),g+=1,g%60===0&&(f+="\n"),f+=e.charAt(63&c)),g+=1,g%60===0&&(f+="\n"),h+=1,3==h&&(h=0);return h>0&&(f+=e.charAt(b),g+=1,g%60===0&&(f+="\n"),f+="=",g+=1),1==h&&(g%60===0&&(f+="\n"),f+="="),f}function d(a){var b,c,d="",f=0,g=0,h=a.length;for(c=0;h>c;c++)b=e.indexOf(a.charAt(c)),b>=0&&(f&&(d+=String.fromCharCode(g|b>>6-f&255)),f=f+2&7,g=b<>c,d.count++})}var e={prio:0,algo:r.encryption_cipher};for(var f in b)try{f!==p.symmetric.plaintext&&f!==p.symmetric.idea&&p.read(p.symmetric,f)&&b[f].count===a.length&&b[f].prio>e.prio&&(e=b[f])}catch(g){}return e.algo}var o=a("./packet"),p=a("./enums.js"),q=a("./encoding/armor.js"),r=a("./config"),s=a("./util");d.prototype.packetlist2structure=function(a){for(var b,c,d,e=0;ethis.primaryKey.created.getTime()+24*this.primaryKey.expirationTimeV3*3600*1e3)return p.keyStatus.expired;for(var a=!1,b=0;bthis.primaryKey.created.getTime()+1e3*c.selfCertificate.keyExpirationTime?p.keyStatus.expired:p.keyStatus.valid:p.keyStatus.invalid},d.prototype.getExpirationTime=function(){if(3==this.primaryKey.version)return h(this.primaryKey);if(4==this.primaryKey.version){var a=this.getPrimaryUser();return a?h(this.primaryKey,a.selfCertificate):null}},d.prototype.getPrimaryUser=function(){for(var a,b=null,c=0;cd.created)&&(b=this.users[c],a=d)}return b?{user:b,selfCertificate:a}:null},d.prototype.update=function(a){var b=this;if(a.verifyPrimaryKey()!==p.keyStatus.invalid){if(this.primaryKey.getFingerprint()!==a.primaryKey.getFingerprint())throw new Error("Key update method: fingerprints of keys not equal");if(this.isPublic()&&a.isPrivate()){var c=(this.subKeys&&this.subKeys.length)===(a.subKeys&&a.subKeys.length)&&(!this.subKeys||this.subKeys.every(function(b){return a.subKeys.some(function(a){return b.subKey.getFingerprint()===a.subKey.getFingerprint()})}));if(!c)throw new Error("Cannot update public key with private key if subkey mismatch");this.primaryKey=a.primaryKey}this.revocationSignature||!a.revocationSignature||a.revocationSignature.isExpired()||!a.revocationSignature.verified&&!a.revocationSignature.verify(a.primaryKey,{key:a.primaryKey})||(this.revocationSignature=a.revocationSignature),i(a,this,"directSignatures"),a.users.forEach(function(a){for(var c=!1,d=0;db?-1:b>a?1:0}),b[0]},j.prototype.verify=function(a){if(!this.selfCertifications)return p.keyStatus.no_self_cert;for(var b,c=0;cthis.subKey.created.getTime()+24*this.subKey.expirationTimeV3*3600*1e3?p.keyStatus.expired:this.bindingSignature?this.bindingSignature.isExpired()?p.keyStatus.expired:this.bindingSignature.verified||this.bindingSignature.verify(a,{key:a,bind:this.subKey})?4==this.subKey.version&&this.bindingSignature.keyNeverExpires===!1&&Date.now()>this.subKey.created.getTime()+1e3*this.bindingSignature.keyExpirationTime?p.keyStatus.expired:p.keyStatus.valid:p.keyStatus.invalid:p.keyStatus.invalid},k.prototype.getExpirationTime=function(){return h(this.subKey,this.bindingSignature)},k.prototype.update=function(a,b){if(this.verify(b)!==p.keyStatus.invalid){if(this.subKey.getFingerprint()!==a.subKey.getFingerprint())throw new Error("SubKey update method: fingerprints of subkeys not equal");this.subKey.tag===p.packet.publicSubkey&&a.subKey.tag===p.packet.secretSubkey&&(this.subKey=a.subKey),this.revocationSignature||!a.revocationSignature||a.revocationSignature.isExpired()||!a.revocationSignature.verified&&!a.revocationSignature.verify(b,{key:b,bind:this.subKey})||(this.revocationSignature=a.revocationSignature)}},c.Key=d,c.readArmored=l,c.generate=m,c.getPreferredSymAlgo=n},{"./config":4,"./encoding/armor.js":28,"./enums.js":30,"./packet":40,"./util":61}],33:[function(a,b){b.exports=a("./keyring.js"),b.exports.localstore=a("./localstore.js")},{"./keyring.js":34,"./localstore.js":35}],34:[function(a,b){function c(b){this.storeHandler=b||new(a("./localstore.js")),this.publicKeys=new d(this.storeHandler.loadPublic()),this.privateKeys=new d(this.storeHandler.loadPrivate())}function d(a){this.keys=a}function e(a,b){a=a.toLowerCase();for(var c=b.getUserIds(),d=0;d")[0].trim().toLowerCase(),keyEmail==a)return!0;return!1}function f(a,b){return 16===a.length?a===b.getKeyId().toHex():a===b.getFingerprint() -}{var g=(a("../enums.js"),a("../key.js"));a("../util.js")}b.exports=c,c.prototype.store=function(){this.storeHandler.storePublic(this.publicKeys.keys),this.storeHandler.storePrivate(this.privateKeys.keys)},c.prototype.clear=function(){this.publicKeys.keys=[],this.privateKeys.keys=[]},c.prototype.getKeysForId=function(a,b){var c=[];return c=c.concat(this.publicKeys.getForId(a,b)||[]),c=c.concat(this.privateKeys.getForId(a,b)||[]),c.length?c:null},c.prototype.removeKeysForId=function(a){var b=[];return b=b.concat(this.publicKeys.removeForId(a)||[]),b=b.concat(this.privateKeys.removeForId(a)||[]),b.length?b:null},c.prototype.getAllKeys=function(){return this.publicKeys.keys.concat(this.privateKeys.keys)},d.prototype.getForAddress=function(a){for(var b=[],c=0;c=0;e--){var m=new h.Signature;if(m.signatureType=g,m.hashAlgorithm=k.prefer_hash_algorithm,m.publicKeyAlgorithm=l.algorithm,!l.isDecrypted)throw new Error("Private key is not decrypted.");m.sign(l,c),b.push(m)}return new d(b)},d.prototype.verify=function(a){var b=[],c=this.unwrapCompressed(),d=c.packets.filterByTag(i.packet.literal);if(1!==d.length)throw new Error("Can only verify message with one literal data packet.");var e=c.packets.filterByTag(i.packet.signature);return a.forEach(function(a){for(var c=0;ce?(d=a.charCodeAt(0),b=1):255>e?(d=(a.charCodeAt(0)-192<<8)+a.charCodeAt(1)+192,b=2):255==e&&(d=c.readNumber(a.substr(1,4)),b=5),{len:d,offset:b}},writeSimpleLength:function(a){var b="";return 192>a?b+=String.fromCharCode(a):a>191&&8384>a?(b+=String.fromCharCode((a-192>>8)+192),b+=String.fromCharCode(a-192&255)):(b+=String.fromCharCode(255),b+=c.writeNumber(a,4)),b},writeHeader:function(a,b){var c="";return c+=String.fromCharCode(192|a),c+=this.writeSimpleLength(b)},writeOldHeader:function(a,b){var d="";return 256>b?(d+=String.fromCharCode(128|a<<2),d+=String.fromCharCode(b)):65536>b?(d+=String.fromCharCode(128|a<<2|1),d+=c.writeNumber(b,2)):(d+=String.fromCharCode(128|a<<2|2),d+=c.writeNumber(b,4)),d},read:function(a,b,d){if(null===a||a.length<=b||a.substring(b).length<2||0===(128&a.charCodeAt(b)))throw new Error("Error during parsing. This message / key is probably not containing a valid OpenPGP format.");var e,f=b,g=-1,h=-1;h=0,0!==(64&a.charCodeAt(f))&&(h=1);var i;h?g=63&a.charCodeAt(f):(g=(63&a.charCodeAt(f))>>2,i=3&a.charCodeAt(f)),f++;var j=null,k=-1;if(h)if(a.charCodeAt(f)<192)e=a.charCodeAt(f++),c.print_debug("1 byte length:"+e);else if(a.charCodeAt(f)>=192&&a.charCodeAt(f)<224)e=(a.charCodeAt(f++)-192<<8)+a.charCodeAt(f++)+192,c.print_debug("2 byte length:"+e);else if(a.charCodeAt(f)>223&&a.charCodeAt(f)<255){e=1<<(31&a.charCodeAt(f++)),c.print_debug("4 byte length:"+e);var l=f+e;j=a.substring(f,f+e);for(var m;;){if(a.charCodeAt(l)<192){m=a.charCodeAt(l++),e+=m,j+=a.substring(l,l+m),l+=m;break}if(a.charCodeAt(l)>=192&&a.charCodeAt(l)<224){m=(a.charCodeAt(l++)-192<<8)+a.charCodeAt(l++)+192,e+=m,j+=a.substring(l,l+m),l+=m;break}if(!(a.charCodeAt(l)>223&&a.charCodeAt(l)<255)){l++,m=a.charCodeAt(l++)<<24|a.charCodeAt(l++)<<16|a[l++].charCodeAt()<<8|a.charCodeAt(l++),j+=a.substring(l,l+m),e+=m,l+=m;break}m=1<<(31&a.charCodeAt(l++)),e+=m,j+=a.substring(l,l+m),l+=m}k=l-f}else f++,e=a.charCodeAt(f++)<<24|a.charCodeAt(f++)<<16|a.charCodeAt(f++)<<8|a.charCodeAt(f++);else switch(i){case 0:e=a.charCodeAt(f++);break;case 1:e=a.charCodeAt(f++)<<8|a.charCodeAt(f++);break;case 2:e=a.charCodeAt(f++)<<24|a.charCodeAt(f++)<<16|a.charCodeAt(f++)<<8|a.charCodeAt(f++);break;default:e=d}return-1==k&&(k=e),null===j&&(j=a.substring(f,f+k)),{tag:g,packet:j,offset:f+k}}}},{"../enums.js":30,"../util.js":61}],45:[function(a,b){function c(){this.length=0}b.exports=c;var d=a("./packet.js"),e=a("./all_packets.js"),f=a("../enums.js");c.prototype.read=function(a){for(var b=0;be;e++)d.push(this[e]);return d},c.prototype.concat=function(a){if(a)for(var b=0;bj&&if.length)throw new Error("Error reading MPI @:"+i);return i+6}throw new Error("Version "+this.version+" of the key packet is unsupported.")},c.prototype.readPublicKey=c.prototype.read,c.prototype.write=function(){var a=String.fromCharCode(this.version);a+=d.writeDate(this.created),3==this.version&&(a+=d.writeNumber(this.expirationTimeV3,2)),a+=String.fromCharCode(g.write(g.publicKey,this.algorithm));for(var b=h.getPublicMpiCount(this.algorithm),c=0;b>c;c++)a+=this.mpi[c].write();return a},c.prototype.writePublicKey=c.prototype.write,c.prototype.writeOld=function(){var a=this.writePublicKey();return String.fromCharCode(153)+d.writeNumber(a.length,2)+a},c.prototype.getKeyId=function(){return this.keyid?this.keyid:(this.keyid=new f,4==this.version?this.keyid.read(d.hex2bin(this.getFingerprint()).substr(12,8)):3==this.version&&this.keyid.read(this.mpi[0].write().substr(-8)),this.keyid)},c.prototype.getFingerprint=function(){if(this.fingerprint)return this.fingerprint;var a="";if(4==this.version)a=this.writeOld(),this.fingerprint=h.hash.sha1(a);else if(3==this.version){for(var b=h.getPublicMpiCount(this.algorithm),c=0;b>c;c++)a+=this.mpi[c].toBytes();this.fingerprint=h.hash.md5(a)}return this.fingerprint=d.hexstrdump(this.fingerprint),this.fingerprint},c.prototype.getBitSize=function(){return 8*this.mpi[0].byteLength()},c.prototype.postCloneTypeFix=function(){for(var a=0;ad;d++){var e=new f;b+=e.read(a.substr(b)),this.encrypted.push(e)}},c.prototype.write=function(){var a=String.fromCharCode(this.version);a+=this.publicKeyId.write(),a+=String.fromCharCode(g.write(g.publicKey,this.publicKeyAlgorithm));for(var b=0;bo&&kc;){var d=f.readSimpleLength(a.substr(c));c+=d.offset,this.read_sub_packet(a.substr(c,d.len)),c+=d.len}return c}var c=0;switch(this.version=a.charCodeAt(c++),this.version){case 3:5!=a.charCodeAt(c++)&&e.print_debug("packet/signature.js\ninvalid One-octet length of following hashed material.MUST be 5. @:"+(c-1));var d=c;this.signatureType=a.charCodeAt(c++),this.created=e.readDate(a.substr(c,4)),c+=4,this.signatureData=a.substring(d,c),this.issuerKeyId.read(a.substring(c,c+8)),c+=8,this.publicKeyAlgorithm=a.charCodeAt(c++),this.hashAlgorithm=a.charCodeAt(c++);break;case 4:this.signatureType=a.charCodeAt(c++),this.publicKeyAlgorithm=a.charCodeAt(c++),this.hashAlgorithm=a.charCodeAt(c++),c+=b.call(this,a.substr(c),!0),this.signatureData=a.substr(0,c);var g=c;c+=b.call(this,a.substr(c),!1),this.unhashedSubpackets=a.substr(g,c-g);break;default:throw new Error("Version "+version+" of the signature is unsupported.")}this.signedHashValue=a.substr(c,2),c+=2,this.signature=a.substr(c)},c.prototype.write=function(){return this.signatureData+(this.unhashedSubpackets?this.unhashedSubpackets:e.writeNumber(0,2))+this.signedHashValue+this.signature},c.prototype.sign=function(a,b){var c=g.write(g.signature,this.signatureType),d=g.write(g.publicKey,this.publicKeyAlgorithm),e=g.write(g.hash,this.hashAlgorithm),f=String.fromCharCode(4);f+=String.fromCharCode(c),f+=String.fromCharCode(d),f+=String.fromCharCode(e),this.issuerKeyId=a.getKeyId(),f+=this.write_all_sub_packets(),this.signatureData=f;var i=this.calculateTrailer(),j=this.toSign(c,b)+this.signatureData+i,k=h.hash.digest(e,j);this.signedHashValue=k.substr(0,2),this.signature=h.signature.sign(e,d,a.mpi,j)},c.prototype.write_all_sub_packets=function(){var a=g.signatureSubpacket,b="",c="";if(null!==this.created&&(b+=d(a.signature_creation_time,e.writeDate(this.created))),null!==this.signatureExpirationTime&&(b+=d(a.signature_expiration_time,e.writeNumber(this.signatureExpirationTime,4))),null!==this.exportable&&(b+=d(a.exportable_certification,String.fromCharCode(this.exportable?1:0))),null!==this.trustLevel&&(c=String.fromCharCode(this.trustLevel)+String.fromCharCode(this.trustAmount),b+=d(a.trust_signature,c)),null!==this.regularExpression&&(b+=d(a.regular_expression,this.regularExpression)),null!==this.revocable&&(b+=d(a.revocable,String.fromCharCode(this.revocable?1:0))),null!==this.keyExpirationTime&&(b+=d(a.key_expiration_time,e.writeNumber(this.keyExpirationTime,4))),null!==this.preferredSymmetricAlgorithms&&(c=e.bin2str(this.preferredSymmetricAlgorithms),b+=d(a.preferred_symmetric_algorithms,c)),null!==this.revocationKeyClass&&(c=String.fromCharCode(this.revocationKeyClass),c+=String.fromCharCode(this.revocationKeyAlgorithm),c+=this.revocationKeyFingerprint,b+=d(a.revocation_key,c)),this.issuerKeyId.isNull()||(b+=d(a.issuer,this.issuerKeyId.write())),null!==this.notation)for(var f in this.notation)if(this.notation.hasOwnProperty(f)){var h=this.notation[f];c=String.fromCharCode(128),c+=String.fromCharCode(0),c+=String.fromCharCode(0),c+=String.fromCharCode(0),c+=e.writeNumber(f.length,2),c+=e.writeNumber(h.length,2),c+=f+h,b+=d(a.notation_data,c)}return null!==this.preferredHashAlgorithms&&(c=e.bin2str(this.preferredHashAlgorithms),b+=d(a.preferred_hash_algorithms,c)),null!==this.preferredCompressionAlgorithms&&(c=e.bin2str(this.preferredCompressionAlgorithms),b+=d(a.preferred_compression_algorithms,c)),null!==this.keyServerPreferences&&(c=e.bin2str(this.keyServerPreferences),b+=d(a.key_server_preferences,c)),null!==this.preferredKeyServer&&(b+=d(a.preferred_key_server,this.preferredKeyServer)),null!==this.isPrimaryUserID&&(b+=d(a.primary_user_id,String.fromCharCode(this.isPrimaryUserID?1:0))),null!==this.policyURI&&(b+=d(a.policy_uri,this.policyURI)),null!==this.keyFlags&&(c=e.bin2str(this.keyFlags),b+=d(a.key_flags,c)),null!==this.signersUserId&&(b+=d(a.signers_user_id,this.signersUserId)),null!==this.reasonForRevocationFlag&&(c=String.fromCharCode(this.reasonForRevocationFlag),c+=this.reasonForRevocationString,b+=d(a.reason_for_revocation,c)),null!==this.features&&(c=e.bin2str(this.features),b+=d(a.features,c)),null!==this.signatureTargetPublicKeyAlgorithm&&(c=String.fromCharCode(this.signatureTargetPublicKeyAlgorithm),c+=String.fromCharCode(this.signatureTargetHashAlgorithm),c+=this.signatureTargetHash,b+=d(a.signature_target,c)),null!==this.embeddedSignature&&(b+=d(a.embedded_signature,this.embeddedSignature.write())),b=e.writeNumber(b.length,2)+b},c.prototype.read_sub_packet=function(a){function b(a,b){this[a]=[];for(var c=0;c0&&4>d?k=1:17==d&&(k=2);for(var l=[],m=0,n=0;k>n;n++)l[n]=new i,m+=l[n].read(this.signature.substr(m));return this.verified=h.signature.verify(d,e,l,a.mpi,f+this.signatureData+j),this.verified},c.prototype.isExpired=function(){return this.signatureNeverExpires?!1:Date.now()>this.created.getTime()+1e3*this.signatureExpirationTime},c.prototype.postCloneTypeFix=function(){this.issuerKeyId=j.fromClone(this.issuerKeyId)}},{"../crypto":19,"../enums.js":30,"../type/keyid.js":58,"../type/mpi.js":59,"../util.js":61,"./packet.js":44}],52:[function(a,b){function c(){this.tag=e.packet.symEncryptedIntegrityProtected,this.encrypted=null,this.modification=!1,this.packets=null}b.exports=c;var d=(a("../util.js"),a("../crypto")),e=a("../enums.js");c.prototype.read=function(a){var b=a.charCodeAt(0);if(1!=b)throw new Error("Invalid packet version.");this.encrypted=a.substr(1)},c.prototype.write=function(){return String.fromCharCode(1)+this.encrypted},c.prototype.encrypt=function(a,b){var c=this.packets.write(),e=d.getPrefixRandom(a),f=e+e.charAt(e.length-2)+e.charAt(e.length-1),g=c;g+=String.fromCharCode(211),g+=String.fromCharCode(20),g+=d.hash.sha1(f+g),this.encrypted=d.cfb.encrypt(e,a,g,b,!1).substring(0,f.length+g.length)},c.prototype.decrypt=function(a,b){var c=d.cfb.decrypt(a,b,this.encrypted,!1);this.hash=d.hash.sha1(d.cfb.mdc(a,b,this.encrypted)+c.substring(0,c.length-20));var e=c.substr(c.length-20,20);if(this.hash!=e)throw new Error("Modification detected.");this.packets.read(c.substr(0,c.length-22))}},{"../crypto":19,"../enums.js":30,"../util.js":61}],53:[function(a,b){function c(){this.tag=e.packet.symEncryptedSessionKey,this.sessionKeyEncryptionAlgorithm=null,this.sessionKeyAlgorithm="aes256",this.encrypted=null,this.s2k=new d}var d=a("../type/s2k.js"),e=a("../enums.js"),f=a("../crypto");b.exports=c,c.prototype.read=function(a){this.version=a.charCodeAt(0);var b=e.read(e.symmetric,a.charCodeAt(1)),c=this.s2k.read(a.substr(2)),d=c+2;d>4)+a},c.prototype.read=function(a){var b=0;switch(this.type=d.read(d.s2k,a.charCodeAt(b++)),this.algorithm=d.read(d.hash,a.charCodeAt(b++)),this.type){case"simple":break;case"salted":this.salt=a.substr(b,8),b+=8;break;case"iterated":this.salt=a.substr(b,8),b+=8,this.c=a.charCodeAt(b++);break;case"gnu":if("GNU"!=a.substr(b,3))throw new Error("Unknown s2k type.");b+=3;var c=1e3+a.charCodeAt(b++);if(1001!=c)throw new Error("Unknown s2k gnu protection mode.");this.type=c;break;default:throw new Error("Unknown s2k type.")}return b},c.prototype.write=function(){var a=String.fromCharCode(d.write(d.s2k,this.type));switch(a+=String.fromCharCode(d.write(d.hash,this.algorithm)),this.type){case"simple":break;case"salted":a+=this.salt;break;case"iterated":a+=this.salt,a+=String.fromCharCode(this.c)}return a},c.prototype.produce_key=function(a,b){function c(b,c){var e=d.write(d.hash,c.algorithm);switch(c.type){case"simple":return f.hash.digest(e,b+a);case"salted":return f.hash.digest(e,b+c.salt+a);case"iterated":var g=[],h=c.get_count();for(data=c.salt+a;g.length*data.lengthh&&(g=g.substr(0,h)),f.hash.digest(e,b+g)}}a=e.encode_utf8(a);for(var g="",h="";g.length<=b;)g+=c(h,this),h+=String.fromCharCode(0);return g.substr(0,b)},b.exports.fromClone=function(a){var b=new c;return this.algorithm=a.algorithm,this.type=a.type,this.c=a.c,this.salt=a.salt,b}},{"../crypto":19,"../enums.js":30,"../util.js":61}],61:[function(a,b){var c=a("./config");b.exports={readNumber:function(a){for(var b=0,c=0;cd;d++)c+=String.fromCharCode(a>>8*(b-d-1)&255);return c},readDate:function(a){var b=this.readNumber(a),c=new Date;return c.setTime(1e3*b),c},writeDate:function(a){var b=Math.round(a.getTime()/1e3);return this.writeNumber(b,4)},emailRegEx:/^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/,hexdump:function(a){for(var b,c=[],d=a.length,e=0,f=0;d>e;){for(b=a.charCodeAt(e++).toString(16);b.length<2;)b="0"+b;c.push(" "+b),f++,f%32===0&&c.push("\n ")}return c.join("")},hexstrdump:function(a){if(null===a)return"";for(var b,c=[],d=a.length,e=0;d>e;){for(b=a.charCodeAt(e++).toString(16);b.length<2;)b="0"+b;c.push(""+b)}return c.join("")},hex2bin:function(a){for(var b="",c=0;ce;){for(b=a[e++].toString(16);b.length<2;)b="0"+b;c.push(""+b)}return c.join("")},encode_utf8:function(a){return unescape(encodeURIComponent(a))},decode_utf8:function(a){if("string"!=typeof a)throw new Error('Parameter "utf8" is not of type string');try{return decodeURIComponent(escape(a))}catch(b){return a}},bin2str:function(a){for(var b=[],c=0;c=0;d--)c[d]>>=b%8,d>0&&(c[d]|=c[d-1]<<8-b%8&255);return util.bin2str(c)},get_hashAlgorithmString:function(a){switch(a){case 1:return"MD5";case 2:return"SHA1";case 3:return"RIPEMD160";case 8:return"SHA256";case 9:return"SHA384";case 10:return"SHA512";case 11:return"SHA224"}return"unknown"}}},{"./config":4}],62:[function(a,b){function c(a){this.worker=new Worker(a||"openpgp.worker.js"),this.worker.onmessage=this.onMessage.bind(this),this.worker.onerror=function(a){throw new Error("Unhandled error in openpgp worker: "+a.message+" ("+a.filename+":"+a.lineno+")")},this.seedRandom(h),this.tasks=[]}var d=a("../crypto"),e=a("../packet"),f=a("../key.js"),g=a("../type/keyid.js"),h=(a("../enums.js"),5e4),i=2e4;c.prototype.onMessage=function(a){var b=a.data;switch(b.event){case"method-return":this.tasks.shift()(b.err?new Error(b.err):null,b.data);break;case"request-seed":this.seedRandom(i);break;default:throw new Error("Unknown Worker Event.")}},c.prototype.seedRandom=function(a){var b=this.getRandomBuffer(a);this.worker.postMessage({event:"seed-random",buf:b})},c.prototype.getRandomBuffer=function(a){if(!a)return null;var b=new Uint8Array(a);return d.random.getRandomValues(b),b},c.prototype.terminate=function(){this.worker.terminate()},c.prototype.encryptMessage=function(a,b,c){a=a.map(function(a){return a.toPacketlist()}),this.worker.postMessage({event:"encrypt-message",keys:a,text:b}),this.tasks.push(c)},c.prototype.signAndEncryptMessage=function(a,b,c,d){a=a.map(function(a){return a.toPacketlist()}),b=b.toPacketlist(),this.worker.postMessage({event:"sign-and-encrypt-message",publicKeys:a,privateKey:b,text:c}),this.tasks.push(d)},c.prototype.decryptMessage=function(a,b,c){a=a.toPacketlist(),this.worker.postMessage({event:"decrypt-message",privateKey:a,message:b}),this.tasks.push(c)},c.prototype.decryptAndVerifyMessage=function(a,b,c,d){a=a.toPacketlist(),b=b.map(function(a){return a.toPacketlist()}),this.worker.postMessage({event:"decrypt-and-verify-message",privateKey:a,publicKeys:b,message:c}),this.tasks.push(function(a,b){b&&(b.signatures=b.signatures.map(function(a){return a.keyid=g.fromClone(a.keyid),a})),d(a,b)})},c.prototype.signClearMessage=function(a,b,c){a=a.map(function(a){return a.toPacketlist()}),this.worker.postMessage({event:"sign-clear-message",privateKeys:a,text:b}),this.tasks.push(c)},c.prototype.verifyClearSignedMessage=function(a,b,c){a=a.map(function(a){return a.toPacketlist()}),this.worker.postMessage({event:"verify-clear-signed-message",publicKeys:a,message:b}),this.tasks.push(function(a,b){b&&(b.signatures=b.signatures.map(function(a){return a.keyid=g.fromClone(a.keyid),a})),c(a,b)})},c.prototype.generateKeyPair=function(a,b,c,d,g){this.worker.postMessage({event:"generate-key-pair",keyType:a,numBits:b,userId:c,passphrase:d}),this.tasks.push(function(a,b){if(b){var c=e.List.fromStructuredClone(b.key);b.key=new f.Key(c)}g(a,b)})},c.prototype.decryptKey=function(a,b,c){a=a.toPacketlist(),this.worker.postMessage({event:"decrypt-key",privateKey:a,password:b}),this.tasks.push(function(a,b){if(b){var d=e.List.fromStructuredClone(b);b=new f.Key(d)}c(a,b)})},c.prototype.decryptKeyPacket=function(a,b,c,d){a=a.toPacketlist(),this.worker.postMessage({event:"decrypt-key-packet",privateKey:a,keyIds:b,password:c}),this.tasks.push(function(a,b){if(b){var c=e.List.fromStructuredClone(b);b=new f.Key(c)}d(a,b)})},b.exports=c},{"../crypto":19,"../enums.js":30,"../key.js":32,"../packet":40,"../type/keyid.js":58}]},{},[31])(31)}); \ No newline at end of file +for(p=3==H?c?new Array(0,32,2):new Array(30,-2,-2):c?new Array(0,32,2,62,30,-2,64,96,2):new Array(94,62,-2,32,64,2,30,-2,-2),c&&(b=e(b,h),F=b.length),result="",tempresult="",1==d&&(q=g.charCodeAt(E++)<<24|g.charCodeAt(E++)<<16|g.charCodeAt(E++)<<8|g.charCodeAt(E++),s=g.charCodeAt(E++)<<24|g.charCodeAt(E++)<<16|g.charCodeAt(E++)<<8|g.charCodeAt(E++),E=0);F>E;){for(n=b.charCodeAt(E++)<<24|b.charCodeAt(E++)<<16|b.charCodeAt(E++)<<8|b.charCodeAt(E++),o=b.charCodeAt(E++)<<24|b.charCodeAt(E++)<<16|b.charCodeAt(E++)<<8|b.charCodeAt(E++),1==d&&(c?(n^=q,o^=s):(r=q,t=s,q=n,s=o)),k=252645135&(n>>>4^o),o^=k,n^=k<<4,k=65535&(n>>>16^o),o^=k,n^=k<<16,k=858993459&(o>>>2^n),n^=k,o^=k<<2,k=16711935&(o>>>8^n),n^=k,o^=k<<8,k=1431655765&(n>>>1^o),o^=k,n^=k<<1,n=n<<1|n>>>31,o=o<<1|o>>>31,j=0;H>j;j+=3){for(u=p[j+1],v=p[j+2],i=p[j];i!=u;i+=v)l=o^a[i],m=(o>>>4|o<<28)^a[i+1],k=n,n=o,o=k^(x[l>>>24&63]|z[l>>>16&63]|B[l>>>8&63]|D[63&l]|w[m>>>24&63]|y[m>>>16&63]|A[m>>>8&63]|C[63&m]);k=n,n=o,o=k}n=n>>>1|n<<31,o=o>>>1|o<<31,k=1431655765&(n>>>1^o),o^=k,n^=k<<1,k=16711935&(o>>>8^n),n^=k,o^=k<<8,k=858993459&(o>>>2^n),n^=k,o^=k<<2,k=65535&(n>>>16^o),o^=k,n^=k<<16,k=252645135&(n>>>4^o),o^=k,n^=k<<4,1==d&&(c?(q=n,s=o):(n^=r,o^=t)),tempresult+=String.fromCharCode(n>>>24,n>>>16&255,n>>>8&255,255&n,o>>>24,o>>>16&255,o>>>8&255,255&o),G+=8,512==G&&(result+=tempresult,tempresult="",G=0)}return result+=tempresult,c||(result=f(result,h)),result}function d(a){pc2bytes0=new Array(0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964),pc2bytes1=new Array(0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697),pc2bytes2=new Array(0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272),pc2bytes3=new Array(0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144),pc2bytes4=new Array(0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256),pc2bytes5=new Array(0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488),pc2bytes6=new Array(0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746),pc2bytes7=new Array(0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568),pc2bytes8=new Array(0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578),pc2bytes9=new Array(0,268435456,8,268435464,0,268435456,8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488),pc2bytes10=new Array(0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800),pc2bytes11=new Array(0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744),pc2bytes12=new Array(0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128),pc2bytes13=new Array(0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261);for(var b,c,d,e=a.length>8?3:1,f=new Array(32*e),g=new Array(0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0),h=0,j=0,k=0;e>k;k++)for(left=a.charCodeAt(h++)<<24|a.charCodeAt(h++)<<16|a.charCodeAt(h++)<<8|a.charCodeAt(h++),right=a.charCodeAt(h++)<<24|a.charCodeAt(h++)<<16|a.charCodeAt(h++)<<8|a.charCodeAt(h++),d=252645135&(left>>>4^right),right^=d,left^=d<<4,d=65535&(right>>>-16^left),left^=d,right^=d<<-16,d=858993459&(left>>>2^right),right^=d,left^=d<<2,d=65535&(right>>>-16^left),left^=d,right^=d<<-16,d=1431655765&(left>>>1^right),right^=d,left^=d<<1,d=16711935&(right>>>8^left),left^=d,right^=d<<8,d=1431655765&(left>>>1^right),right^=d,left^=d<<1,d=left<<8|right>>>20&240,left=right<<24|right<<8&16711680|right>>>8&65280|right>>>24&240,right=d,i=0;i>>26,right=right<<2|right>>>26):(left=left<<1|left>>>27,right=right<<1|right>>>27),left&=-15,right&=-15,b=pc2bytes0[left>>>28]|pc2bytes1[left>>>24&15]|pc2bytes2[left>>>20&15]|pc2bytes3[left>>>16&15]|pc2bytes4[left>>>12&15]|pc2bytes5[left>>>8&15]|pc2bytes6[left>>>4&15],c=pc2bytes7[right>>>28]|pc2bytes8[right>>>24&15]|pc2bytes9[right>>>20&15]|pc2bytes10[right>>>16&15]|pc2bytes11[right>>>12&15]|pc2bytes12[right>>>8&15]|pc2bytes13[right>>>4&15],d=65535&(c>>>16^b),f[j++]=b^d,f[j++]=c^d<<16;return f}function e(a,b){var c=8-a.length%8;return 2==b&&8>c?a+=" ".substr(0,c):1==b?a+=String.fromCharCode(c,c,c,c,c,c,c,c).substr(0,c):!b&&8>c&&(a+="\x00\x00\x00\x00\x00\x00\x00\x00".substr(0,c)),a}function f(a,b){if(2==b)a=a.replace(/ *$/g,"");else if(1==b){var c=a.charCodeAt(a.length-1);a=a.substr(0,a.length-c)}else b||(a=a.replace(/\0*$/g,""));return a}function g(a){this.key=[];for(var b=0;3>b;b++)this.key.push(a.substr(8*b,8));this.encrypt=function(a){return j.str2bin(c(d(this.key[2]),c(d(this.key[1]),c(d(this.key[0]),j.bin2str(a),!0,0,null,null),!1,0,null,null),!0,0,null,null))}}function h(a){this.key=a,this.encrypt=function(a,b){var e=d(this.key);return j.str2bin(c(e,j.bin2str(a),!0,0,null,b))},this.decrypt=function(a,b){var e=d(this.key);return j.str2bin(c(e,j.bin2str(a),!1,0,null,b))}}var j=a("../../util.js");g.keySize=g.prototype.keySize=24,g.blockSize=g.prototype.blockSize=8,b.exports={des:g,originalDes:h}},{"../../util.js":61}],10:[function(a,b){var c=a("./des.js");b.exports={des:c.originalDes,tripledes:c.des,cast5:a("./cast5.js"),twofish:a("./twofish.js"),blowfish:a("./blowfish.js"),idea:function(){throw new Error("IDEA symmetric-key algorithm not implemented")}};var d=a("./aes.js");for(var e in d)b.exports["aes"+e]=d[e]},{"./aes.js":6,"./blowfish.js":7,"./cast5.js":8,"./des.js":9,"./twofish.js":11}],11:[function(a,b){function c(a,b){return(a<>>32-b)&j}function d(a,b){return a[b]|a[b+1]<<8|a[b+2]<<16|a[b+3]<<24}function e(a,b,c){a.splice(b,4,255&c,c>>>8&255,c>>>16&255,c>>>24&255)}function f(a,b){return a>>>8*b&255}function g(){function a(a){function b(a){return a^a>>2^[0,90,180,238][3&a]}function e(a){return a^a>>1^a>>2^[0,238,180,90][3&a]}function g(a,b){var c,d,e;for(c=0;8>c;c++)d=b>>>24,b=b<<8&j|a>>>24,a=a<<8&j,e=d<<1,128&d&&(e^=333),b^=d^e<<16,e^=d>>>1,1&d&&(e^=166),b^=e<<24|e<<8;return b}function h(a,b){var c,d,e,f;return c=b>>4,d=15&b,e=A[a][c^d],f=B[a][E[d]^F[c]],D[a][E[f]^F[e]]<<4|C[a][e^f]}function i(a,b){var c=f(a,0),d=f(a,1),e=f(a,2),g=f(a,3);switch(q){case 4:c=G[1][c]^f(b[3],0),d=G[0][d]^f(b[3],1),e=G[0][e]^f(b[3],2),g=G[1][g]^f(b[3],3);case 3:c=G[1][c]^f(b[2],0),d=G[1][d]^f(b[2],1),e=G[0][e]^f(b[2],2),g=G[0][g]^f(b[2],3);case 2:c=G[0][G[0][c]^f(b[1],0)]^f(b[0],0),d=G[0][G[1][d]^f(b[1],1)]^f(b[0],1),e=G[1][G[0][e]^f(b[1],2)]^f(b[0],2),g=G[1][G[1][g]^f(b[1],3)]^f(b[0],3)}return H[0][c]^H[1][d]^H[2][e]^H[3][g]}o=a;var k,l,m,n,p,q,r,u,v,w=[],x=[],y=[],z=[],A=[[8,1,7,13,6,15,3,2,0,11,5,9,14,12,10,4],[2,8,11,13,15,7,6,14,3,1,9,4,0,10,12,5]],B=[[14,12,11,8,1,2,3,5,15,4,10,6,7,0,9,13],[1,14,2,11,4,12,3,7,6,13,10,5,15,9,0,8]],C=[[11,10,5,14,6,13,9,0,12,8,15,3,2,4,7,1],[4,12,7,5,1,6,9,10,0,14,13,8,2,11,3,15]],D=[[13,7,15,4,1,2,6,14,9,11,3,0,8,5,12,10],[11,9,5,1,12,3,13,14,6,4,7,15,2,0,8,10]],E=[0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15],F=[0,9,2,11,4,13,6,15,8,1,10,3,12,5,14,7],G=[[],[]],H=[[],[],[],[]];for(o=o.slice(0,32),k=o.length;16!=k&&24!=k&&32!=k;)o[k++]=0;for(k=0;k>2]=d(o,k);for(k=0;256>k;k++)G[0][k]=h(0,k),G[1][k]=h(1,k);for(k=0;256>k;k++)r=G[1][k],u=b(r),v=e(r),H[0][k]=r+(u<<8)+(v<<16)+(v<<24),H[2][k]=u+(v<<8)+(r<<16)+(v<<24),r=G[0][k],u=b(r),v=e(r),H[1][k]=v+(v<<8)+(u<<16)+(r<<24),H[3][k]=u+(r<<8)+(v<<16)+(u<<24);for(q=y.length/2,k=0;q>k;k++)l=y[k+k],w[k]=l,m=y[k+k+1],x[k]=m,z[q-k-1]=g(l,m);for(k=0;40>k;k+=2)l=16843009*k,m=l+16843009,l=i(l,w),m=c(i(m,x),8),s[k]=l+m&j,s[k+1]=c(l+2*m,9);for(k=0;256>k;k++)switch(l=m=n=p=k,q){case 4:l=G[1][l]^f(z[3],0),m=G[0][m]^f(z[3],1),n=G[0][n]^f(z[3],2),p=G[1][p]^f(z[3],3);case 3:l=G[1][l]^f(z[2],0),m=G[1][m]^f(z[2],1),n=G[0][n]^f(z[2],2),p=G[0][p]^f(z[2],3);case 2:t[0][k]=H[0][G[0][G[0][l]^f(z[1],0)]^f(z[0],0)],t[1][k]=H[1][G[0][G[1][m]^f(z[1],1)]^f(z[0],1)],t[2][k]=H[2][G[1][G[0][n]^f(z[1],2)]^f(z[0],2)],t[3][k]=H[3][G[1][G[1][p]^f(z[1],3)]^f(z[0],3)]}}function b(a){return t[0][f(a,0)]^t[1][f(a,1)]^t[2][f(a,2)]^t[3][f(a,3)]}function g(a){return t[0][f(a,3)]^t[1][f(a,0)]^t[2][f(a,1)]^t[3][f(a,2)]}function h(a,d){var e=b(d[0]),f=g(d[1]);d[2]=c(d[2]^e+f+s[4*a+8]&j,31),d[3]=c(d[3],1)^e+2*f+s[4*a+9]&j,e=b(d[2]),f=g(d[3]),d[0]=c(d[0]^e+f+s[4*a+10]&j,31),d[1]=c(d[1],1)^e+2*f+s[4*a+11]&j}function i(a,d){var e=b(d[0]),f=g(d[1]);d[2]=c(d[2],1)^e+f+s[4*a+10]&j,d[3]=c(d[3]^e+2*f+s[4*a+11]&j,31),e=b(d[2]),f=g(d[3]),d[0]=c(d[0],1)^e+f+s[4*a+8]&j,d[1]=c(d[1]^e+2*f+s[4*a+9]&j,31)}function k(){s=[],t=[[],[],[],[]]}function l(a,b){p=a,q=b;for(var c=[d(p,q)^s[0],d(p,q+4)^s[1],d(p,q+8)^s[2],d(p,q+12)^s[3]],f=0;8>f;f++)h(f,c);return e(p,q,c[2]^s[4]),e(p,q+4,c[3]^s[5]),e(p,q+8,c[0]^s[6]),e(p,q+12,c[1]^s[7]),q+=16,p}function m(a,b){p=a,q=b;for(var c=[d(p,q)^s[4],d(p,q+4)^s[5],d(p,q+8)^s[6],d(p,q+12)^s[7]],f=7;f>=0;f--)i(f,c);e(p,q,c[2]^s[0]),e(p,q+4,c[3]^s[1]),e(p,q+8,c[0]^s[2]),e(p,q+12,c[1]^s[3]),q+=16}function n(){return p}var o=null,p=null,q=-1,r=null;r="twofish";var s=[],t=[[],[],[],[]];return{name:"twofish",blocksize:16,open:a,close:k,encrypt:l,decrypt:m,finalize:n}}function h(a){this.tf=g(),this.tf.open(k.str2bin(a),0),this.encrypt=function(a){return this.tf.encrypt(i(a),0)}}function i(a){for(var b=[],c=0;c=64;){for(k=0;16>k;++k)b[k]=c.getInt32();for(;64>k;++k)d=b[k-2],d=(d>>>17|d<<15)^(d>>>19|d<<13)^d>>>10,e=b[k-15],e=(e>>>7|e<<25)^(e>>>18|e<<14)^e>>>3,b[k]=d+b[k-7]+e+b[k-16]&4294967295;for(l=a.h0,m=a.h1,n=a.h2,o=a.h3,p=a.h4,q=a.h5,r=a.h6,s=a.h7,k=0;64>k;++k)h=(p>>>6|p<<26)^(p>>>11|p<<21)^(p>>>25|p<<7),i=r^p&(q^r),f=(l>>>2|l<<30)^(l>>>13|l<<19)^(l>>>22|l<<10),j=l&m|n&(l^m),d=s+h+i+g[k]+b[k],e=f+j,s=r,r=q,q=p,p=o+d&4294967295,o=n,n=m,m=l,l=d+e&4294967295;a.h0=a.h0+l&4294967295,a.h1=a.h1+m&4294967295,a.h2=a.h2+n&4294967295,a.h3=a.h3+o&4294967295,a.h4=a.h4+p&4294967295,a.h5=a.h5+q&4294967295,a.h6=a.h6+r&4294967295,a.h7=a.h7+s&4294967295,t-=64}};c.create=function(){f||h();var a=null,b=d.createBuffer(),c=new Array(64),g={algorithm:"sha256",blockLength:64,digestLength:32,messageLength:0};return g.start=function(){return g.messageLength=0,b=d.createBuffer(),a={h0:1779033703,h1:3144134277,h2:1013904242,h3:2773480762,h4:1359893119,h5:2600822924,h6:528734635,h7:1541459225},g},g.start(),g.update=function(e,f){return"utf8"===f&&(e=d.encodeUtf8(e)),g.messageLength+=e.length,b.putBytes(e),i(a,c,b),(b.read>2048||0===b.length())&&b.compact(),g},g.digest=function(){var f=g.messageLength,h=d.createBuffer();h.putBytes(b.bytes()),h.putBytes(e.substr(0,64-(f+8)%64)),h.putInt32(f>>>29&255),h.putInt32(f<<3&4294967295);var j={h0:a.h0,h1:a.h1,h2:a.h2,h3:a.h3,h4:a.h4,h5:a.h5,h6:a.h6,h7:a.h7};i(j,c,h);var k=d.createBuffer();return k.putInt32(j.h0),k.putInt32(j.h1),k.putInt32(j.h2),k.putInt32(j.h3),k.putInt32(j.h4),k.putInt32(j.h5),k.putInt32(j.h6),k.putInt32(j.h7),k},g}},{"./forge_util.js":14}],14:[function(a,b){var c=b.exports={};c.isArray=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},c.isArrayBuffer=function(a){return"undefined"!=typeof ArrayBuffer&&a instanceof ArrayBuffer};var d=[];"undefined"!=typeof Int8Array&&d.push(Int8Array),"undefined"!=typeof Uint8Array&&d.push(Uint8Array),"undefined"!=typeof Uint8ClampedArray&&d.push(Uint8ClampedArray),"undefined"!=typeof Int16Array&&d.push(Int16Array),"undefined"!=typeof Uint16Array&&d.push(Uint16Array),"undefined"!=typeof Int32Array&&d.push(Int32Array),"undefined"!=typeof Uint32Array&&d.push(Uint32Array),"undefined"!=typeof Float32Array&&d.push(Float32Array),"undefined"!=typeof Float64Array&&d.push(Float64Array),c.isArrayBufferView=function(a){for(var b=0;b0;)1&b&&(c+=a),b>>>=1,b>0&&(a+=a);return this.data=c,this},c.ByteBuffer.prototype.putBytes=function(a){return this.data+=a,this},c.ByteBuffer.prototype.putString=function(a){return this.data+=c.encodeUtf8(a),this},c.ByteBuffer.prototype.putInt16=function(a){return this.data+=String.fromCharCode(a>>8&255)+String.fromCharCode(255&a),this},c.ByteBuffer.prototype.putInt24=function(a){return this.data+=String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(255&a),this},c.ByteBuffer.prototype.putInt32=function(a){return this.data+=String.fromCharCode(a>>24&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(255&a),this},c.ByteBuffer.prototype.putInt16Le=function(a){return this.data+=String.fromCharCode(255&a)+String.fromCharCode(a>>8&255),this},c.ByteBuffer.prototype.putInt24Le=function(a){return this.data+=String.fromCharCode(255&a)+String.fromCharCode(a>>8&255)+String.fromCharCode(a>>16&255),this},c.ByteBuffer.prototype.putInt32Le=function(a){return this.data+=String.fromCharCode(255&a)+String.fromCharCode(a>>8&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>24&255),this},c.ByteBuffer.prototype.putInt=function(a,b){do b-=8,this.data+=String.fromCharCode(a>>b&255);while(b>0);return this},c.ByteBuffer.prototype.putSignedInt=function(a,b){return 0>a&&(a+=2<0);return b},c.ByteBuffer.prototype.getSignedInt=function(a){var b=this.getInt(a),c=2<=c&&(b-=c<<1),b},c.ByteBuffer.prototype.getBytes=function(a){var b;return a?(a=Math.min(this.length(),a),b=this.data.slice(this.read,this.read+a),this.read+=a):0===a?b="":(b=0===this.read?this.data:this.data.slice(this.read),this.clear()),b},c.ByteBuffer.prototype.bytes=function(a){return"undefined"==typeof a?this.data.slice(this.read):this.data.slice(this.read,this.read+a)},c.ByteBuffer.prototype.at=function(a){return this.data.charCodeAt(this.read+a)},c.ByteBuffer.prototype.setAt=function(a,b){return this.data=this.data.substr(0,this.read+a)+String.fromCharCode(b)+this.data.substr(this.read+a+1),this},c.ByteBuffer.prototype.last=function(){return this.data.charCodeAt(this.data.length-1)},c.ByteBuffer.prototype.copy=function(){var a=c.createBuffer(this.data);return a.read=this.read,a},c.ByteBuffer.prototype.compact=function(){return this.read>0&&(this.data=this.data.slice(this.read),this.read=0),this},c.ByteBuffer.prototype.clear=function(){return this.data="",this.read=0,this},c.ByteBuffer.prototype.truncate=function(a){var b=Math.max(0,this.length()-a);return this.data=this.data.substr(this.read,b),this.read=0,this},c.ByteBuffer.prototype.toHex=function(){for(var a="",b=this.read;bc&&(a+="0"),a+=c.toString(16)}return a},c.ByteBuffer.prototype.toString=function(){return c.decodeUtf8(this.bytes())},c.createBuffer=function(a,b){return b=b||"raw",void 0!==a&&"utf8"===b&&(a=c.encodeUtf8(a)),new c.ByteBuffer(a)},c.fillString=function(a,b){for(var c="";b>0;)1&b&&(c+=a),b>>>=1,b>0&&(a+=a);return c},c.xorBytes=function(a,b,c){for(var d="",e="",f="",g=0,h=0;c>0;--c,++g)e=a.charCodeAt(g)^b.charCodeAt(g),h>=10&&(d+=f,f="",h=0),f+=String.fromCharCode(e),++h;return d+=f},c.hexToBytes=function(a){var b="",c=0;for(a.length&!0&&(c=1,b+=String.fromCharCode(parseInt(a[0],16)));c>24&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(255&a)};var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",f=[62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];c.encode64=function(a,b){for(var c,d,f,g="",h="",i=0;i>2),g+=e.charAt((3&c)<<4|d>>4),isNaN(d)?g+="==":(g+=e.charAt((15&d)<<2|f>>6),g+=isNaN(f)?"=":e.charAt(63&f)),b&&g.length>b&&(h+=g.substr(0,b)+"\r\n",g=g.substr(b));return h+=g},c.decode64=function(a){a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var b,c,d,e,g="",h=0;h>4),64!==d&&(g+=String.fromCharCode((15&c)<<4|d>>2),64!==e&&(g+=String.fromCharCode((3&d)<<6|e)));return g},c.encodeUtf8=function(a){return unescape(encodeURIComponent(a))},c.decodeUtf8=function(a){return decodeURIComponent(escape(a))}},{}],15:[function(a,b){var c=a("./sha.js"),d=a("./forge_sha256.js");b.exports={md5:a("./md5.js"),sha1:c.sha1,sha224:c.sha224,sha256:c.sha256,sha384:c.sha384,sha512:c.sha512,ripemd:a("./ripe-md.js"),digest:function(a,b){switch(a){case 1:return this.md5(b);case 2:return this.sha1(b);case 3:return this.ripemd(b);case 8:var c=d.create();return c.update(b),c.digest().getBytes();case 9:return this.sha384(b);case 10:return this.sha512(b);case 11:return this.sha224(b);default:throw new Error("Invalid hash function.")}},getHashByteLength:function(a){switch(a){case 1:return 16;case 2:case 3:return 20;case 8:return 32;case 9:return 48;case 10:return 64;case 11:return 28;default:throw new Error("Invalid hash algorithm.")}}}},{"./forge_sha256.js":13,"./md5.js":16,"./ripe-md.js":17,"./sha.js":18}],16:[function(a,b){function c(a,b){var c=a[0],d=a[1],i=a[2],j=a[3];c=e(c,d,i,j,b[0],7,-680876936),j=e(j,c,d,i,b[1],12,-389564586),i=e(i,j,c,d,b[2],17,606105819),d=e(d,i,j,c,b[3],22,-1044525330),c=e(c,d,i,j,b[4],7,-176418897),j=e(j,c,d,i,b[5],12,1200080426),i=e(i,j,c,d,b[6],17,-1473231341),d=e(d,i,j,c,b[7],22,-45705983),c=e(c,d,i,j,b[8],7,1770035416),j=e(j,c,d,i,b[9],12,-1958414417),i=e(i,j,c,d,b[10],17,-42063),d=e(d,i,j,c,b[11],22,-1990404162),c=e(c,d,i,j,b[12],7,1804603682),j=e(j,c,d,i,b[13],12,-40341101),i=e(i,j,c,d,b[14],17,-1502002290),d=e(d,i,j,c,b[15],22,1236535329),c=f(c,d,i,j,b[1],5,-165796510),j=f(j,c,d,i,b[6],9,-1069501632),i=f(i,j,c,d,b[11],14,643717713),d=f(d,i,j,c,b[0],20,-373897302),c=f(c,d,i,j,b[5],5,-701558691),j=f(j,c,d,i,b[10],9,38016083),i=f(i,j,c,d,b[15],14,-660478335),d=f(d,i,j,c,b[4],20,-405537848),c=f(c,d,i,j,b[9],5,568446438),j=f(j,c,d,i,b[14],9,-1019803690),i=f(i,j,c,d,b[3],14,-187363961),d=f(d,i,j,c,b[8],20,1163531501),c=f(c,d,i,j,b[13],5,-1444681467),j=f(j,c,d,i,b[2],9,-51403784),i=f(i,j,c,d,b[7],14,1735328473),d=f(d,i,j,c,b[12],20,-1926607734),c=g(c,d,i,j,b[5],4,-378558),j=g(j,c,d,i,b[8],11,-2022574463),i=g(i,j,c,d,b[11],16,1839030562),d=g(d,i,j,c,b[14],23,-35309556),c=g(c,d,i,j,b[1],4,-1530992060),j=g(j,c,d,i,b[4],11,1272893353),i=g(i,j,c,d,b[7],16,-155497632),d=g(d,i,j,c,b[10],23,-1094730640),c=g(c,d,i,j,b[13],4,681279174),j=g(j,c,d,i,b[0],11,-358537222),i=g(i,j,c,d,b[3],16,-722521979),d=g(d,i,j,c,b[6],23,76029189),c=g(c,d,i,j,b[9],4,-640364487),j=g(j,c,d,i,b[12],11,-421815835),i=g(i,j,c,d,b[15],16,530742520),d=g(d,i,j,c,b[2],23,-995338651),c=h(c,d,i,j,b[0],6,-198630844),j=h(j,c,d,i,b[7],10,1126891415),i=h(i,j,c,d,b[14],15,-1416354905),d=h(d,i,j,c,b[5],21,-57434055),c=h(c,d,i,j,b[12],6,1700485571),j=h(j,c,d,i,b[3],10,-1894986606),i=h(i,j,c,d,b[10],15,-1051523),d=h(d,i,j,c,b[1],21,-2054922799),c=h(c,d,i,j,b[8],6,1873313359),j=h(j,c,d,i,b[15],10,-30611744),i=h(i,j,c,d,b[6],15,-1560198380),d=h(d,i,j,c,b[13],21,1309151649),c=h(c,d,i,j,b[4],6,-145523070),j=h(j,c,d,i,b[11],10,-1120210379),i=h(i,j,c,d,b[2],15,718787259),d=h(d,i,j,c,b[9],21,-343485551),a[0]=n(c,a[0]),a[1]=n(d,a[1]),a[2]=n(i,a[2]),a[3]=n(j,a[3])}function d(a,b,c,d,e,f){return b=n(n(b,a),n(d,f)),n(b<>>32-e,c)}function e(a,b,c,e,f,g,h){return d(b&c|~b&e,a,b,f,g,h)}function f(a,b,c,e,f,g,h){return d(b&e|c&~e,a,b,f,g,h)}function g(a,b,c,e,f,g,h){return d(b^c^e,a,b,f,g,h)}function h(a,b,c,e,f,g,h){return d(c^(b|~e),a,b,f,g,h)}function i(a){txt="";var b,d=a.length,e=[1732584193,-271733879,-1732584194,271733878];for(b=64;b<=a.length;b+=64)c(e,j(a.substring(b-64,b)));a=a.substring(b-64);var f=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(b=0;b>2]|=a.charCodeAt(b)<<(b%4<<3);if(f[b>>2]|=128<<(b%4<<3),b>55)for(c(e,f),b=0;16>b;b++)f[b]=0;return f[14]=8*d,c(e,f),e}function j(a){var b,c=[];for(b=0;64>b;b+=4)c[b>>2]=a.charCodeAt(b)+(a.charCodeAt(b+1)<<8)+(a.charCodeAt(b+2)<<16)+(a.charCodeAt(b+3)<<24);return c}function k(a){for(var b="",c=0;4>c;c++)b+=p[a>>8*c+4&15]+p[a>>8*c&15];return b}function l(a){for(var b=0;b>16)+(b>>16)+(c>>16);return d<<16|65535&c}var o=a("../../util.js");b.exports=function(a){var b=m(a),c=o.hex2bin(b);return c};var p="0123456789abcdef".split("");"5d41402abc4b2a76b9719d911017c592"!=m("hello")},{"../../util.js":61}],17:[function(a,b){function c(a,b){return new Number(a<>>32-b)}function d(a,b,c){return new Number(a^b^c)}function e(a,b,c){return new Number(a&b|~a&c)}function f(a,b,c){return new Number((a|~b)^c)}function g(a,b,c){return new Number(a&c|b&~c)}function h(a,b,c){return new Number(a^(b|~c))}function i(a,b,i,j,k,l,m,n){switch(n){case 0:a+=d(b,i,j)+l+0;break;case 1:a+=e(b,i,j)+l+1518500249;break;case 2:a+=f(b,i,j)+l+1859775393;break;case 3:a+=g(b,i,j)+l+2400959708;break;case 4:a+=h(b,i,j)+l+2840853838;break;case 5:a+=h(b,i,j)+l+1352829926;break;case 6:a+=g(b,i,j)+l+1548603684;break;case 7:a+=f(b,i,j)+l+1836072691;break;case 8:a+=e(b,i,j)+l+2053994217;break;case 9:a+=d(b,i,j)+l+0;break;default:throw new Error("Bogus round number")}a=c(a,m)+k,i=c(i,10),a&=4294967295,b&=4294967295,i&=4294967295,j&=4294967295,k&=4294967295;var o=[];return o[0]=a,o[1]=b,o[2]=i,o[3]=j,o[4]=k,o[5]=l,o[6]=m,o}function j(a){a[0]=1732584193,a[1]=4023233417,a[2]=2562383102,a[3]=271733878,a[4]=3285377520}function k(a,b){blockA=[],blockB=[];var c,d,e;for(d=0;5>d;d++)blockA[d]=new Number(a[d]),blockB[d]=new Number(a[d]);var f=0;for(e=0;5>e;e++)for(d=0;16>d;d++)c=i(blockA[(f+0)%5],blockA[(f+1)%5],blockA[(f+2)%5],blockA[(f+3)%5],blockA[(f+4)%5],b[s[e][d]],r[e][d],e),blockA[(f+0)%5]=c[0],blockA[(f+1)%5]=c[1],blockA[(f+2)%5]=c[2],blockA[(f+3)%5]=c[3],blockA[(f+4)%5]=c[4],f+=4;for(f=0,e=5;10>e;e++)for(d=0;16>d;d++)c=i(blockB[(f+0)%5],blockB[(f+1)%5],blockB[(f+2)%5],blockB[(f+3)%5],blockB[(f+4)%5],b[s[e][d]],r[e][d],e),blockB[(f+0)%5]=c[0],blockB[(f+1)%5]=c[1],blockB[(f+2)%5]=c[2],blockB[(f+3)%5]=c[3],blockB[(f+4)%5]=c[4],f+=4;blockB[3]+=blockA[2]+a[1],a[1]=a[2]+blockA[3]+blockB[4],a[2]=a[3]+blockA[4]+blockB[0],a[3]=a[4]+blockA[0]+blockB[1],a[4]=a[0]+blockA[1]+blockB[2],a[0]=blockB[3]}function l(a){for(var b=0;16>b;b++)a[b]=0}function m(a,b,c,d){var e=new Array(16);l(e);for(var f=0,g=0;(63&c)>g;g++)e[g>>>2]^=(255&b.charCodeAt(f++))<<8*(3&g);e[c>>>2&15]^=1<<8*(3&c)+7,(63&c)>55&&(k(a,e),e=new Array(16),l(e)),e[14]=c<<3,e[15]=c>>>29|d<<3,k(a,e)}function n(a){var b=(255&a.charCodeAt(3))<<24;return b|=(255&a.charCodeAt(2))<<16,b|=(255&a.charCodeAt(1))<<8,b|=255&a.charCodeAt(0)}function o(a){var b,c,d=new Array(q/32),e=new Array(q/8);j(d),b=a.length;var f=new Array(16);l(f);var g,h=0;for(c=b;c>63;c-=64){for(g=0;16>g;g++)f[g]=n(a.substr(h,4)),h+=4;k(d,f)}for(m(d,a.substr(h),b,0),g=0;q/8>g;g+=4)e[g]=255&d[g>>>2],e[g+1]=d[g>>>2]>>>8&255,e[g+2]=d[g>>>2]>>>16&255,e[g+3]=d[g>>>2]>>>24&255;return e}function p(a){for(var b=o(a),c="",d=0;q/8>d;d++)c+=String.fromCharCode(b[d]);return c}var q=160,r=[[11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8],[7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12],[11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5],[11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12],[9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6],[8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6],[9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11],[9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5],[15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8],[8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]],s=[[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8],[3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12],[1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2],[4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13],[5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12],[6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2],[15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13],[8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14],[12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]];b.exports=p},{}],18:[function(a,b){var c=function(){var a=8,b="",c=0,d=function(a,b){this.highOrder=a,this.lowOrder=b},e=function(b){var c,d=[],e=(1<c;c+=a)d[c>>5]|=(b.charCodeAt(c/a)&e)<<32-a-c%32;return d},f=function(a){var b,c,d=[],e=a.length;for(b=0;e>b;b+=2){if(c=parseInt(a.substr(b,2),16),isNaN(c))throw new Error("INVALID HEX STRING");d[b>>3]|=c<<24-4*(b%8)}return d},g=function(a){var b,d,e=c?"0123456789ABCDEF":"0123456789abcdef",f="",g=4*a.length;for(b=0;g>b;b+=1)d=a[b>>2]>>8*(3-b%4),f+=e.charAt(d>>4&15)+e.charAt(15&d);return f},h=function(a){var c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",g="",h=4*a.length;for(c=0;h>c;c+=3)for(e=(a[c>>2]>>8*(3-c%4)&255)<<16|(a[c+1>>2]>>8*(3-(c+1)%4)&255)<<8|a[c+2>>2]>>8*(3-(c+2)%4)&255,d=0;4>d;d+=1)g+=8*c+6*d<=32*a.length?f.charAt(e>>6*(3-d)&63):b;return g},i=function(a){for(var b="",c=255,d=0;d<32*a.length;d+=8)b+=String.fromCharCode(a[d>>5]>>>24-d%32&c);return b},j=function(a,b){return a<>>32-b},k=function(a,b){return a>>>b|a<<32-b},l=function(a,b){return 32>=b?new d(a.highOrder>>>b|a.lowOrder<<32-b,a.lowOrder>>>b|a.highOrder<<32-b):new d(a.lowOrder>>>b|a.highOrder<<32-b,a.highOrder>>>b|a.lowOrder<<32-b)},m=function(a,b){return a>>>b},n=function(a,b){return 32>=b?new d(a.highOrder>>>b,a.lowOrder>>>b|a.highOrder<<32-b):new d(0,a.highOrder<<32-b)},o=function(a,b,c){return a^b^c},p=function(a,b,c){return a&b^~a&c},q=function(a,b,c){return new d(a.highOrder&b.highOrder^~a.highOrder&c.highOrder,a.lowOrder&b.lowOrder^~a.lowOrder&c.lowOrder)},r=function(a,b,c){return a&b^a&c^b&c},s=function(a,b,c){return new d(a.highOrder&b.highOrder^a.highOrder&c.highOrder^b.highOrder&c.highOrder,a.lowOrder&b.lowOrder^a.lowOrder&c.lowOrder^b.lowOrder&c.lowOrder)},t=function(a){return k(a,2)^k(a,13)^k(a,22)},u=function(a){var b=l(a,28),c=l(a,34),e=l(a,39);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},v=function(a){return k(a,6)^k(a,11)^k(a,25)},w=function(a){var b=l(a,14),c=l(a,18),e=l(a,41);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},x=function(a){return k(a,7)^k(a,18)^m(a,3)},y=function(a){var b=l(a,1),c=l(a,8),e=n(a,7);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},z=function(a){return k(a,17)^k(a,19)^m(a,10)},A=function(a){var b=l(a,19),c=l(a,61),e=n(a,6);return new d(b.highOrder^c.highOrder^e.highOrder,b.lowOrder^c.lowOrder^e.lowOrder)},B=function(a,b){var c=(65535&a)+(65535&b),d=(a>>>16)+(b>>>16)+(c>>>16); +return(65535&d)<<16|65535&c},C=function(a,b,c,d){var e=(65535&a)+(65535&b)+(65535&c)+(65535&d),f=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16);return(65535&f)<<16|65535&e},D=function(a,b,c,d,e){var f=(65535&a)+(65535&b)+(65535&c)+(65535&d)+(65535&e),g=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16)+(f>>>16);return(65535&g)<<16|65535&f},E=function(a,b){var c,e,f,g;return c=(65535&a.lowOrder)+(65535&b.lowOrder),e=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c>>>16),f=(65535&e)<<16|65535&c,c=(65535&a.highOrder)+(65535&b.highOrder)+(e>>>16),e=(a.highOrder>>>16)+(b.highOrder>>>16)+(c>>>16),g=(65535&e)<<16|65535&c,new d(g,f)},F=function(a,b,c,e){var f,g,h,i;return f=(65535&a.lowOrder)+(65535&b.lowOrder)+(65535&c.lowOrder)+(65535&e.lowOrder),g=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(e.lowOrder>>>16)+(f>>>16),h=(65535&g)<<16|65535&f,f=(65535&a.highOrder)+(65535&b.highOrder)+(65535&c.highOrder)+(65535&e.highOrder)+(g>>>16),g=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(e.highOrder>>>16)+(f>>>16),i=(65535&g)<<16|65535&f,new d(i,h)},G=function(a,b,c,e,f){var g,h,i,j;return g=(65535&a.lowOrder)+(65535&b.lowOrder)+(65535&c.lowOrder)+(65535&e.lowOrder)+(65535&f.lowOrder),h=(a.lowOrder>>>16)+(b.lowOrder>>>16)+(c.lowOrder>>>16)+(e.lowOrder>>>16)+(f.lowOrder>>>16)+(g>>>16),i=(65535&h)<<16|65535&g,g=(65535&a.highOrder)+(65535&b.highOrder)+(65535&c.highOrder)+(65535&e.highOrder)+(65535&f.highOrder)+(h>>>16),h=(a.highOrder>>>16)+(b.highOrder>>>16)+(c.highOrder>>>16)+(e.highOrder>>>16)+(f.highOrder>>>16)+(g>>>16),j=(65535&h)<<16|65535&g,new d(j,i)},H=function(a,b){var c,d,e,f,g,h,i,k,l,m=[],n=p,q=o,s=r,t=j,u=B,v=D,w=[1732584193,4023233417,2562383102,271733878,3285377520],x=[1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782];for(a[b>>5]|=128<<24-b%32,a[(b+65>>9<<4)+15]=b,l=a.length,i=0;l>i;i+=16){for(c=w[0],d=w[1],e=w[2],f=w[3],g=w[4],k=0;80>k;k+=1)m[k]=16>k?a[k+i]:t(m[k-3]^m[k-8]^m[k-14]^m[k-16],1),h=20>k?v(t(c,5),n(d,e,f),g,x[k],m[k]):40>k?v(t(c,5),q(d,e,f),g,x[k],m[k]):60>k?v(t(c,5),s(d,e,f),g,x[k],m[k]):v(t(c,5),q(d,e,f),g,x[k],m[k]),g=f,f=e,e=t(d,30),d=c,c=h;w[0]=u(c,w[0]),w[1]=u(d,w[1]),w[2]=u(e,w[2]),w[3]=u(f,w[3]),w[4]=u(g,w[4])}return w},I=function(a,b,c){var e,f,g,h,i,j,k,l,m,n,o,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z=[];for("SHA-224"===c||"SHA-256"===c?(H=64,I=(b+65>>9<<4)+15,L=16,M=1,W=Number,N=B,O=C,P=D,Q=x,R=z,S=t,T=v,V=r,U=p,X=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],o="SHA-224"===c?[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]:[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]):("SHA-384"===c||"SHA-512"===c)&&(H=80,I=(b+128>>10<<5)+31,L=32,M=2,W=d,N=E,O=F,P=G,Q=y,R=A,S=u,T=w,V=s,U=q,X=[new W(1116352408,3609767458),new W(1899447441,602891725),new W(3049323471,3964484399),new W(3921009573,2173295548),new W(961987163,4081628472),new W(1508970993,3053834265),new W(2453635748,2937671579),new W(2870763221,3664609560),new W(3624381080,2734883394),new W(310598401,1164996542),new W(607225278,1323610764),new W(1426881987,3590304994),new W(1925078388,4068182383),new W(2162078206,991336113),new W(2614888103,633803317),new W(3248222580,3479774868),new W(3835390401,2666613458),new W(4022224774,944711139),new W(264347078,2341262773),new W(604807628,2007800933),new W(770255983,1495990901),new W(1249150122,1856431235),new W(1555081692,3175218132),new W(1996064986,2198950837),new W(2554220882,3999719339),new W(2821834349,766784016),new W(2952996808,2566594879),new W(3210313671,3203337956),new W(3336571891,1034457026),new W(3584528711,2466948901),new W(113926993,3758326383),new W(338241895,168717936),new W(666307205,1188179964),new W(773529912,1546045734),new W(1294757372,1522805485),new W(1396182291,2643833823),new W(1695183700,2343527390),new W(1986661051,1014477480),new W(2177026350,1206759142),new W(2456956037,344077627),new W(2730485921,1290863460),new W(2820302411,3158454273),new W(3259730800,3505952657),new W(3345764771,106217008),new W(3516065817,3606008344),new W(3600352804,1432725776),new W(4094571909,1467031594),new W(275423344,851169720),new W(430227734,3100823752),new W(506948616,1363258195),new W(659060556,3750685593),new W(883997877,3785050280),new W(958139571,3318307427),new W(1322822218,3812723403),new W(1537002063,2003034995),new W(1747873779,3602036899),new W(1955562222,1575990012),new W(2024104815,1125592928),new W(2227730452,2716904306),new W(2361852424,442776044),new W(2428436474,593698344),new W(2756734187,3733110249),new W(3204031479,2999351573),new W(3329325298,3815920427),new W(3391569614,3928383900),new W(3515267271,566280711),new W(3940187606,3454069534),new W(4118630271,4000239992),new W(116418474,1914138554),new W(174292421,2731055270),new W(289380356,3203993006),new W(460393269,320620315),new W(685471733,587496836),new W(852142971,1086792851),new W(1017036298,365543100),new W(1126000580,2618297676),new W(1288033470,3409855158),new W(1501505948,4234509866),new W(1607167915,987167468),new W(1816402316,1246189591)],o="SHA-384"===c?[new W(3418070365,3238371032),new W(1654270250,914150663),new W(2438529370,812702999),new W(355462360,4144912697),new W(1731405415,4290775857),new W(41048885895,1750603025),new W(3675008525,1694076839),new W(1203062813,3204075428)]:[new W(1779033703,4089235720),new W(3144134277,2227873595),new W(1013904242,4271175723),new W(2773480762,1595750129),new W(1359893119,2917565137),new W(2600822924,725511199),new W(528734635,4215389547),new W(1541459225,327033209)]),a[b>>5]|=128<<24-b%32,a[I]=b,Y=a.length,J=0;Y>J;J+=L){for(e=o[0],f=o[1],g=o[2],h=o[3],i=o[4],j=o[5],k=o[6],l=o[7],K=0;H>K;K+=1)Z[K]=16>K?new W(a[K*M+J],a[K*M+J+1]):O(R(Z[K-2]),Z[K-7],Q(Z[K-15]),Z[K-16]),m=P(l,T(i),U(i,j,k),X[K],Z[K]),n=N(S(e),V(e,f,g)),l=k,k=j,j=i,i=N(h,m),h=g,g=f,f=e,e=N(m,n);o[0]=N(e,o[0]),o[1]=N(f,o[1]),o[2]=N(g,o[2]),o[3]=N(h,o[3]),o[4]=N(i,o[4]),o[5]=N(j,o[5]),o[6]=N(k,o[6]),o[7]=N(l,o[7])}switch(c){case"SHA-224":return[o[0],o[1],o[2],o[3],o[4],o[5],o[6]];case"SHA-256":return o;case"SHA-384":return[o[0].highOrder,o[0].lowOrder,o[1].highOrder,o[1].lowOrder,o[2].highOrder,o[2].lowOrder,o[3].highOrder,o[3].lowOrder,o[4].highOrder,o[4].lowOrder,o[5].highOrder,o[5].lowOrder];case"SHA-512":return[o[0].highOrder,o[0].lowOrder,o[1].highOrder,o[1].lowOrder,o[2].highOrder,o[2].lowOrder,o[3].highOrder,o[3].lowOrder,o[4].highOrder,o[4].lowOrder,o[5].highOrder,o[5].lowOrder,o[6].highOrder,o[6].lowOrder,o[7].highOrder,o[7].lowOrder];default:throw new Error("Unknown SHA variant")}},J=function(b,c){if(this.sha1=null,this.sha224=null,this.sha256=null,this.sha384=null,this.sha512=null,this.strBinLen=null,this.strToHash=null,"HEX"===c){if(0!==b.length%2)throw new Error("TEXT MUST BE IN BYTE INCREMENTS");this.strBinLen=4*b.length,this.strToHash=f(b)}else{if("ASCII"!==c&&"undefined"!=typeof c)throw new Error("UNKNOWN TEXT INPUT TYPE");this.strBinLen=b.length*a,this.strToHash=e(b)}};return J.prototype={getHash:function(a,b){var c=null,d=this.strToHash.slice();switch(b){case"HEX":c=g;break;case"B64":c=h;break;case"ASCII":c=i;break;default:throw new Error("FORMAT NOT RECOGNIZED")}switch(a){case"SHA-1":return null===this.sha1&&(this.sha1=H(d,this.strBinLen)),c(this.sha1);case"SHA-224":return null===this.sha224&&(this.sha224=I(d,this.strBinLen,a)),c(this.sha224);case"SHA-256":return null===this.sha256&&(this.sha256=I(d,this.strBinLen,a)),c(this.sha256);case"SHA-384":return null===this.sha384&&(this.sha384=I(d,this.strBinLen,a)),c(this.sha384);case"SHA-512":return null===this.sha512&&(this.sha512=I(d,this.strBinLen,a)),c(this.sha512);default:throw new Error("HASH NOT RECOGNIZED")}},getHMAC:function(b,c,d,j){var k,l,m,n,o,p,q,r,s,t=[],u=[];switch(j){case"HEX":k=g;break;case"B64":k=h;break;case"ASCII":k=i;break;default:throw new Error("FORMAT NOT RECOGNIZED")}switch(d){case"SHA-1":m=64,s=160;break;case"SHA-224":m=64,s=224;break;case"SHA-256":m=64,s=256;break;case"SHA-384":m=128,s=384;break;case"SHA-512":m=128,s=512;break;default:throw new Error("HASH NOT RECOGNIZED")}if("HEX"===c){if(0!==b.length%2)throw new Error("KEY MUST BE IN BYTE INCREMENTS");l=f(b),r=4*b.length}else{if("ASCII"!==c)throw new Error("UNKNOWN KEY INPUT TYPE");l=e(b),r=b.length*a}for(n=8*m,q=m/4-1,r/8>m?(l="SHA-1"===d?H(l,r):I(l,r,d),l[q]&=4294967040):m>r/8&&(l[q]&=4294967040),o=0;q>=o;o+=1)t[o]=909522486^l[o],u[o]=1549556828^l[o];return"SHA-1"===d?(p=H(t.concat(this.strToHash),n+this.strBinLen),p=H(u.concat(p),n+s)):(p=I(t.concat(this.strToHash),n+this.strBinLen,d),p=I(u.concat(p),n+s,d)),k(p)}},J}();b.exports={sha1:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-1","ASCII")},sha224:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-224","ASCII")},sha256:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-256","ASCII")},sha384:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-384","ASCII")},sha512:function(a){var b=new c(a,"ASCII");return b.getHash("SHA-512","ASCII")}}},{}],19:[function(a,b){b.exports={cipher:a("./cipher"),hash:a("./hash"),cfb:a("./cfb.js"),publicKey:a("./public_key"),signature:a("./signature.js"),random:a("./random.js"),pkcs1:a("./pkcs1.js")};var c=a("./crypto.js");for(var d in c)b.exports[d]=c[d]},{"./cfb.js":5,"./cipher":10,"./crypto.js":12,"./hash":15,"./pkcs1.js":20,"./public_key":23,"./random.js":26,"./signature.js":27}],20:[function(a,b){function c(a){for(var b,c="";c.lengthb-11)throw new Error("Message too long");var e=c(b-d-3),f=String.fromCharCode(0)+String.fromCharCode(2)+e+String.fromCharCode(0)+a;return f},decode:function(a){0!==a.charCodeAt(0)&&(a=String.fromCharCode(0)+a);for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=2;0!==a.charCodeAt(d)&&d=8&&0===f)return a.substr(d);throw new Error("Decryption error")}},emsa:{encode:function(a,b,c){var e,i=h.digest(a,b);if(i.length!==h.getHashByteLength(a))throw new Error("Invalid hash length");var j="";for(e=0;ec)throw new Error("Intended encoded message length too short");var l="";for(e=0;c-k-3>e;e++)l+=String.fromCharCode(255);var m=String.fromCharCode(0)+String.fromCharCode(1)+l+String.fromCharCode(0)+j;return new g(f.hexstrdump(m),16)}}}},{"../util.js":61,"./crypto.js":12,"./hash":15,"./public_key/jsbn.js":24,"./random.js":26}],21:[function(a,b){function c(){function a(a,b,c,h,i,j){for(var k,l,m,n=g.getLeftNBits(f.digest(a,b),i.bitLength()),o=new d(g.hexstrdump(n),16);;)if(k=e.getRandomBigIntegerInRange(d.ONE,i.subtract(d.ONE)),l=c.modPow(k,h).mod(i),m=k.modInverse(i).multiply(o.add(j.multiply(l))).mod(i),0!=l&&0!=m)break;var p=[];return p[0]=l.toMPI(),p[1]=m.toMPI(),p}function b(a){var b=h.prefer_hash_algorithm;switch(Math.round(a.bitLength()/8)){case 20:return 2!=b&&b>11&&10!=b&&8>b?2:b;case 28:return b>11&&8>b?11:b;case 32:return b>10&&8>b?8:b;default:return g.print_debug("DSA select hash algorithm: returning null for an unknown length of q"),null}}function c(a,b,c,e,h,i,j,k){var l=g.getLeftNBits(f.digest(a,e),i.bitLength()),m=new d(g.hexstrdump(l),16);if(d.ZERO.compareTo(b)>0||b.compareTo(i)>0||d.ZERO.compareTo(c)>0||c.compareTo(i)>0)return g.print_debug("invalid DSA Signature"),null;var n=c.modInverse(i),o=m.multiply(n).mod(i),p=b.multiply(n).mod(i);return j.modPow(o,h).multiply(k.modPow(p,h)).mod(h).mod(i)}this.select_hash_algorithm=b,this.sign=a,this.verify=c}var d=a("./jsbn.js"),e=a("../random.js"),f=a("../hash"),g=a("../../util.js"),h=a("../../config");b.exports=c},{"../../config":4,"../../util.js":61,"../hash":15,"../random.js":26,"./jsbn.js":24}],22:[function(a,b){function c(){function a(a,b,c,f){var g=c.subtract(d.TWO),h=e.getRandomBigIntegerInRange(d.ONE,g);h=h.mod(g).add(d.ONE);var i=[];return i[0]=b.modPow(h,c),i[1]=f.modPow(h,c).multiply(a).mod(c),i}function b(a,b,c,d){return f.print_debug("Elgamal Decrypt:\nc1:"+f.hexstrdump(a.toMPI())+"\nc2:"+f.hexstrdump(b.toMPI())+"\np:"+f.hexstrdump(c.toMPI())+"\nx:"+f.hexstrdump(d.toMPI())),a.modPow(d,c).modInverse(c).multiply(b).mod(c)}this.encrypt=a,this.decrypt=b}var d=a("./jsbn.js"),e=a("../random.js"),f=a("../../util.js");b.exports=c},{"../../util.js":61,"../random.js":26,"./jsbn.js":24}],23:[function(a,b){b.exports={rsa:a("./rsa.js"),elgamal:a("./elgamal.js"),dsa:a("./dsa.js")}},{"./dsa.js":21,"./elgamal.js":22,"./rsa.js":25}],24:[function(a,b){function c(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function d(){return new c(null)}function e(a,b,c,d,e,f){for(;--f>=0;){var g=b*this[a++]+c[d]+e;e=Math.floor(g/67108864),c[d++]=67108863&g}return e}function f(a){return ec.charAt(a)}function g(a,b){var c=fc[a.charCodeAt(b)];return null==c?-1:c}function h(a){for(var b=this.t-1;b>=0;--b)a[b]=this[b];a.t=this.t,a.s=this.s}function i(a){this.t=1,this.s=0>a?-1:0,a>0?this[0]=a:-1>a?this[0]=a+this.DV:this.t=0}function j(a){var b=d();return b.fromInt(a),b}function k(a,b){var d;if(16==b)d=4;else if(8==b)d=3;else if(256==b)d=8;else if(2==b)d=1;else if(32==b)d=5;else{if(4!=b)return void this.fromRadix(a,b);d=2}this.t=0,this.s=0;for(var e=a.length,f=!1,h=0;--e>=0;){var i=8==d?255&a[e]:g(a,e);0>i?"-"==a.charAt(e)&&(f=!0):(f=!1,0==h?this[this.t++]=i:h+d>this.DB?(this[this.t-1]|=(i&(1<>this.DB-h):this[this.t-1]|=i<=this.DB&&(h-=this.DB))}8==d&&0!=(128&a[0])&&(this.s=-1,h>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==a;)--this.t}function m(a){if(this.s<0)return"-"+this.negate().toString(a);var b;if(16==a)b=4;else if(8==a)b=3;else if(2==a)b=1;else if(32==a)b=5;else{if(4!=a)return this.toRadix(a);b=2}var c,d=(1<0)for(i>i)>0&&(e=!0,g=f(c));h>=0;)b>i?(c=(this[h]&(1<>(i+=this.DB-b)):(c=this[h]>>(i-=b)&d,0>=i&&(i+=this.DB,--h)),c>0&&(e=!0),e&&(g+=f(c));return e?g:"0"}function n(){var a=d();return c.ZERO.subTo(this,a),a}function o(){return this.s<0?this.negate():this}function p(a){var b=this.s-a.s;if(0!=b)return b;var c=this.t;if(b=c-a.t,0!=b)return this.s<0?-b:b;for(;--c>=0;)if(0!=(b=this[c]-a[c]))return b;return 0}function q(a){var b,c=1;return 0!=(b=a>>>16)&&(a=b,c+=16),0!=(b=a>>8)&&(a=b,c+=8),0!=(b=a>>4)&&(a=b,c+=4),0!=(b=a>>2)&&(a=b,c+=2),0!=(b=a>>1)&&(a=b,c+=1),c}function r(){return this.t<=0?0:this.DB*(this.t-1)+q(this[this.t-1]^this.s&this.DM)}function s(a,b){var c;for(c=this.t-1;c>=0;--c)b[c+a]=this[c];for(c=a-1;c>=0;--c)b[c]=0;b.t=this.t+a,b.s=this.s}function t(a,b){for(var c=a;c=0;--c)b[c+g+1]=this[c]>>e|h,h=(this[c]&f)<=0;--c)b[c]=0;b[g]=h,b.t=this.t+g+1,b.s=this.s,b.clamp()}function v(a,b){b.s=this.s;var c=Math.floor(a/this.DB);if(c>=this.t)return void(b.t=0);var d=a%this.DB,e=this.DB-d,f=(1<>d;for(var g=c+1;g>d;d>0&&(b[this.t-c-1]|=(this.s&f)<c;)d+=this[c]-a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d-=a.s}b.s=0>d?-1:0,-1>d?b[c++]=this.DV+d:d>0&&(b[c++]=d),b.t=c,b.clamp()}function x(a,b){var d=this.abs(),e=a.abs(),f=d.t;for(b.t=f+e.t;--f>=0;)b[f]=0;for(f=0;f=0;)a[c]=0;for(c=0;c=b.DV&&(a[c+b.t]-=b.DV,a[c+b.t+1]=1)}a.t>0&&(a[a.t-1]+=b.am(c,b[c],a,2*c,0,1)),a.s=0,a.clamp()}function z(a,b,e){var f=a.abs();if(!(f.t<=0)){var g=this.abs();if(g.t0?(f.lShiftTo(k,h),g.lShiftTo(k,e)):(f.copyTo(h),g.copyTo(e));var l=h.t,m=h[l-1];if(0!=m){var n=m*(1<1?h[l-2]>>this.F2:0),o=this.FV/n,p=(1<=0&&(e[e.t++]=1,e.subTo(u,e)),c.ONE.dlShiftTo(l,u),u.subTo(h,h);h.t=0;){var v=e[--s]==m?this.DM:Math.floor(e[s]*o+(e[s-1]+r)*p);if((e[s]+=h.am(0,v,e,t,0,l))0&&e.rShiftTo(k,e),0>i&&c.ZERO.subTo(e,e)}}}function A(a){var b=d();return this.abs().divRemTo(a,null,b),this.s<0&&b.compareTo(c.ZERO)>0&&a.subTo(b,b),b}function B(a){this.m=a}function C(a){return a.s<0||a.compareTo(this.m)>=0?a.mod(this.m):a}function D(a){return a}function E(a){a.divRemTo(this.m,null,a)}function F(a,b,c){a.multiplyTo(b,c),this.reduce(c)}function G(a,b){a.squareTo(b),this.reduce(b)}function H(){if(this.t<1)return 0;var a=this[0];if(0==(1&a))return 0;var b=3&a;return b=b*(2-(15&a)*b)&15,b=b*(2-(255&a)*b)&255,b=b*(2-((65535&a)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV,b>0?this.DV-b:-b}function I(a){this.m=a,this.mp=a.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<0&&this.m.subTo(b,b),b}function K(a){var b=d();return a.copyTo(b),this.reduce(b),b}function L(a){for(;a.t<=this.mt2;)a[a.t++]=0;for(var b=0;b>15)*this.mpl&this.um)<<15)&a.DM;for(c=b+this.m.t,a[c]+=this.m.am(0,d,a,b,0,this.m.t);a[c]>=a.DV;)a[c]-=a.DV,a[++c]++}a.clamp(),a.drShiftTo(this.m.t,a),a.compareTo(this.m)>=0&&a.subTo(this.m,a)}function M(a,b){a.squareTo(b),this.reduce(b)}function N(a,b,c){a.multiplyTo(b,c),this.reduce(c)}function O(){return 0==(this.t>0?1&this[0]:this.s)}function P(a,b){if(a>4294967295||1>a)return c.ONE;var e=d(),f=d(),g=b.convert(this),h=q(a)-1;for(g.copyTo(e);--h>=0;)if(b.sqrTo(e,f),(a&1<0)b.mulTo(f,g,e);else{var i=e;e=f,f=i}return b.revert(e)}function Q(a,b){var c;return c=256>a||b.isEven()?new B(b):new I(b),this.exp(a,c)}function R(){var a=d();return this.copyTo(a),a}function S(){if(this.s<0){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<>24}function U(){return 0==this.t?this.s:this[0]<<16>>16}function V(a){return Math.floor(Math.LN2*this.DB/Math.log(a))}function W(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1}function X(a){if(null==a&&(a=10),0==this.signum()||2>a||a>36)return"0";var b=this.chunkSize(a),c=Math.pow(a,b),e=j(c),f=d(),g=d(),h="";for(this.divRemTo(e,f,g);f.signum()>0;)h=(c+g.intValue()).toString(a).substr(1)+h,f.divRemTo(e,f,g);return g.intValue().toString(a)+h}function Y(a,b){this.fromInt(0),null==b&&(b=10);for(var d=this.chunkSize(b),e=Math.pow(b,d),f=!1,h=0,i=0,j=0;jk?"-"==a.charAt(j)&&0==this.signum()&&(f=!0):(i=b*i+k,++h>=d&&(this.dMultiply(e),this.dAddOffset(i,0),h=0,i=0))}h>0&&(this.dMultiply(Math.pow(b,h)),this.dAddOffset(i,0)),f&&c.ZERO.subTo(this,this)}function Z(a,b,d){if("number"==typeof b)if(2>a)this.fromInt(1);else for(this.fromNumber(a,d),this.testBit(a-1)||this.bitwiseTo(c.ONE.shiftLeft(a-1),fb,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(c.ONE.shiftLeft(a-1),this);else{var e=new Array,f=7&a;e.length=(a>>3)+1,b.nextBytes(e),f>0?e[0]&=(1<0)for(d>d)!=(this.s&this.DM)>>d&&(b[e++]=c|this.s<=0;)8>d?(c=(this[a]&(1<>(d+=this.DB-8)):(c=this[a]>>(d-=8)&255,0>=d&&(d+=this.DB,--a)),(e>0||c!=this.s)&&(b[e++]=c);return b}function _(a){return 0==this.compareTo(a)}function ab(a){return this.compareTo(a)<0?this:a}function bb(a){return this.compareTo(a)>0?this:a}function cb(a,b,c){var d,e,f=Math.min(a.t,this.t);for(d=0;f>d;++d)c[d]=b(this[d],a[d]);if(a.ta?this.rShiftTo(-a,b):this.lShiftTo(a,b),b}function nb(a){var b=d();return 0>a?this.lShiftTo(-a,b):this.rShiftTo(a,b),b}function ob(a){if(0==a)return-1;var b=0;return 0==(65535&a)&&(a>>=16,b+=16),0==(255&a)&&(a>>=8,b+=8),0==(15&a)&&(a>>=4,b+=4),0==(3&a)&&(a>>=2,b+=2),0==(1&a)&&++b,b}function pb(){for(var a=0;a=this.t?0!=this.s:0!=(this[b]&1<c;)d+=this[c]+a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d+=a.s}b.s=0>d?-1:0,d>0?b[c++]=d:-1>d&&(b[c++]=this.DV+d),b.t=c,b.clamp()}function yb(a){var b=d();return this.addTo(a,b),b}function zb(a){var b=d();return this.subTo(a,b),b}function Ab(a){var b=d();return this.multiplyTo(a,b),b}function Bb(){var a=d();return this.squareTo(a),a}function Cb(a){var b=d();return this.divRemTo(a,b,null),b}function Db(a){var b=d();return this.divRemTo(a,null,b),b}function Eb(a){var b=d(),c=d();return this.divRemTo(a,b,c),new Array(b,c)}function Fb(a){this[this.t]=this.am(0,a-1,this,0,0,this.t),++this.t,this.clamp()}function Gb(a,b){if(0!=a){for(;this.t<=b;)this[this.t++]=0;for(this[b]+=a;this[b]>=this.DV;)this[b]-=this.DV,++b>=this.t&&(this[this.t++]=0),++this[b]}}function Hb(){}function Ib(a){return a}function Jb(a,b,c){a.multiplyTo(b,c)}function Kb(a,b){a.squareTo(b)}function Lb(a){return this.exp(a,new Hb)}function Mb(a,b,c){var d=Math.min(this.t+a.t,b);for(c.s=0,c.t=d;d>0;)c[--d]=0;var e;for(e=c.t-this.t;e>d;++d)c[d+this.t]=this.am(0,a[d],c,d,0,this.t);for(e=Math.min(a.t,b);e>d;++d)this.am(0,a[d],c,d,0,b-d);c.clamp()}function Nb(a,b,c){--b;var d=c.t=this.t+a.t-b;for(c.s=0;--d>=0;)c[d]=0;for(d=Math.max(b-this.t,0);d2*this.m.t)return a.mod(this.m);if(a.compareTo(this.m)<0)return a;var b=d();return a.copyTo(b),this.reduce(b),b}function Qb(a){return a}function Rb(a){for(a.drShiftTo(this.m.t-1,this.r2),a.t>this.m.t+1&&(a.t=this.m.t+1,a.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);a.compareTo(this.r2)<0;)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);a.compareTo(this.m)>=0;)a.subTo(this.m,a)}function Sb(a,b){a.squareTo(b),this.reduce(b)}function Tb(a,b,c){a.multiplyTo(b,c),this.reduce(c)}function Ub(a,b){var c,e,f=a.bitLength(),g=j(1);if(0>=f)return g;c=18>f?1:48>f?3:144>f?4:768>f?5:6,e=8>f?new B(b):b.isEven()?new Ob(b):new I(b);var h=new Array,i=3,k=c-1,l=(1<1){var m=d();for(e.sqrTo(h[1],m);l>=i;)h[i]=d(),e.mulTo(m,h[i-2],h[i]),i+=2}var n,o,p=a.t-1,r=!0,s=d();for(f=q(a[p])-1;p>=0;){for(f>=k?n=a[p]>>f-k&l:(n=(a[p]&(1<0&&(n|=a[p-1]>>this.DB+f-k)),i=c;0==(1&n);)n>>=1,--i;if((f-=i)<0&&(f+=this.DB,--p),r)h[n].copyTo(g),r=!1;else{for(;i>1;)e.sqrTo(g,s),e.sqrTo(s,g),i-=2;i>0?e.sqrTo(g,s):(o=g,g=s,s=o),e.mulTo(s,h[n],g)}for(;p>=0&&0==(a[p]&1<f)return b;for(f>e&&(f=e),f>0&&(b.rShiftTo(f,b),c.rShiftTo(f,c));b.signum()>0;)(e=b.getLowestSetBit())>0&&b.rShiftTo(e,b),(e=c.getLowestSetBit())>0&&c.rShiftTo(e,c),b.compareTo(c)>=0?(b.subTo(c,b),b.rShiftTo(1,b)):(c.subTo(b,c),c.rShiftTo(1,c));return f>0&&c.lShiftTo(f,c),c}function Wb(a){if(0>=a)return 0;var b=this.DV%a,c=this.s<0?a-1:0;if(this.t>0)if(0==b)c=this[0]%a;else for(var d=this.t-1;d>=0;--d)c=(b*c+this[d])%a;return c}function Xb(a){var b=a.isEven();if(this.isEven()&&b||0==a.signum())return c.ZERO;for(var d=a.clone(),e=this.clone(),f=j(1),g=j(0),h=j(0),i=j(1);0!=d.signum();){for(;d.isEven();)d.rShiftTo(1,d),b?(f.isEven()&&g.isEven()||(f.addTo(this,f),g.subTo(a,g)),f.rShiftTo(1,f)):g.isEven()||g.subTo(a,g),g.rShiftTo(1,g);for(;e.isEven();)e.rShiftTo(1,e),b?(h.isEven()&&i.isEven()||(h.addTo(this,h),i.subTo(a,i)),h.rShiftTo(1,h)):i.isEven()||i.subTo(a,i),i.rShiftTo(1,i);d.compareTo(e)>=0?(d.subTo(e,d),b&&f.subTo(h,f),g.subTo(i,g)):(e.subTo(d,e),b&&h.subTo(f,h),i.subTo(g,i))}return 0!=e.compareTo(c.ONE)?c.ZERO:i.compareTo(a)>=0?i.subtract(a):i.signum()<0?(i.addTo(a,i),i.signum()<0?i.add(a):i):i}function Yb(a){var b,c=this.abs();if(1==c.t&&c[0]<=gc[gc.length-1]){for(b=0;bd;)d*=gc[e++];for(d=c.modInt(d);e>b;)if(d%gc[b++]==0)return!1}return c.millerRabin(a)}function q(a){var b,c=1;return 0!=(b=a>>>16)&&(a=b,c+=16),0!=(b=a>>8)&&(a=b,c+=8),0!=(b=a>>4)&&(a=b,c+=4),0!=(b=a>>2)&&(a=b,c+=2),0!=(b=a>>1)&&(a=b,c+=1),c}function Zb(){var a=this.toByteArray(),b=8*(a.length-1)+q(a[0]),c="";return c+=String.fromCharCode((65280&b)>>8),c+=String.fromCharCode(255&b),c+=ac.bin2str(a)}function $b(a){var b=this.subtract(c.ONE),e=b.getLowestSetBit();if(0>=e)return!1;var f=b.shiftRight(e);a=a+1>>1,a>gc.length&&(a=gc.length);for(var g,h=d(),i=[],j=0;a>j;++j){for(;g=gc[Math.floor(Math.random()*gc.length)],-1!=i.indexOf(g););i.push(g),h.fromInt(g);var k=h.modPow(f,this);if(0!=k.compareTo(c.ONE)&&0!=k.compareTo(b)){for(var g=1;g++=dc;++dc)fc[cc++]=dc;for(cc="a".charCodeAt(0),dc=10;36>dc;++dc)fc[cc++]=dc;for(cc="A".charCodeAt(0),dc=10;36>dc;++dc)fc[cc++]=dc;B.prototype.convert=C,B.prototype.revert=D,B.prototype.reduce=E,B.prototype.mulTo=F,B.prototype.sqrTo=G,I.prototype.convert=J,I.prototype.revert=K,I.prototype.reduce=L,I.prototype.mulTo=N,I.prototype.sqrTo=M,c.prototype.copyTo=h,c.prototype.fromInt=i,c.prototype.fromString=k,c.prototype.clamp=l,c.prototype.dlShiftTo=s,c.prototype.drShiftTo=t,c.prototype.lShiftTo=u,c.prototype.rShiftTo=v,c.prototype.subTo=w,c.prototype.multiplyTo=x,c.prototype.squareTo=y,c.prototype.divRemTo=z,c.prototype.invDigit=H,c.prototype.isEven=O,c.prototype.exp=P,c.prototype.toString=m,c.prototype.negate=n,c.prototype.abs=o,c.prototype.compareTo=p,c.prototype.bitLength=r,c.prototype.mod=A,c.prototype.modPowInt=Q,c.ZERO=j(0),c.ONE=j(1),c.TWO=j(2),b.exports=c,Hb.prototype.convert=Ib,Hb.prototype.revert=Ib,Hb.prototype.mulTo=Jb,Hb.prototype.sqrTo=Kb,Ob.prototype.convert=Pb,Ob.prototype.revert=Qb,Ob.prototype.reduce=Rb,Ob.prototype.mulTo=Tb,Ob.prototype.sqrTo=Sb;var gc=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],hc=(1<<26)/gc[gc.length-1],c=a("./jsbn.js");c.prototype.chunkSize=V,c.prototype.toRadix=X,c.prototype.fromRadix=Y,c.prototype.fromNumber=Z,c.prototype.bitwiseTo=cb,c.prototype.changeBit=tb,c.prototype.addTo=xb,c.prototype.dMultiply=Fb,c.prototype.dAddOffset=Gb,c.prototype.multiplyLowerTo=Mb,c.prototype.multiplyUpperTo=Nb,c.prototype.modInt=Wb,c.prototype.millerRabin=$b,c.prototype.clone=R,c.prototype.intValue=S,c.prototype.byteValue=T,c.prototype.shortValue=U,c.prototype.signum=W,c.prototype.toByteArray=$,c.prototype.equals=_,c.prototype.min=ab,c.prototype.max=bb,c.prototype.and=eb,c.prototype.or=gb,c.prototype.xor=ib,c.prototype.andNot=kb,c.prototype.not=lb,c.prototype.shiftLeft=mb,c.prototype.shiftRight=nb,c.prototype.getLowestSetBit=pb,c.prototype.bitCount=rb,c.prototype.testBit=sb,c.prototype.setBit=ub,c.prototype.clearBit=vb,c.prototype.flipBit=wb,c.prototype.add=yb,c.prototype.subtract=zb,c.prototype.multiply=Ab,c.prototype.divide=Cb,c.prototype.remainder=Db,c.prototype.divideAndRemainder=Eb,c.prototype.modPow=Ub,c.prototype.modInverse=Xb,c.prototype.pow=Lb,c.prototype.gcd=Vb,c.prototype.isProbablePrime=Yb,c.prototype.toMPI=Zb,c.prototype.square=Bb +},{"../../util.js":61,"./jsbn.js":24}],25:[function(a,b){function c(){function a(a){for(var b=0;b>1;for(d.e=parseInt(b,16),d.ee=new g(b,16);;){for(;d.p=new g(a-f,1,e),0!==d.p.subtract(g.ONE).gcd(d.ee).compareTo(g.ONE)||!d.p.isProbablePrime(10););for(;d.q=new g(f,1,e),0!==d.q.subtract(g.ONE).gcd(d.ee).compareTo(g.ONE)||!d.q.isProbablePrime(10););if(d.p.compareTo(d.q)<=0){var h=d.p;d.p=d.q,d.q=h}var i=d.p.subtract(g.ONE),j=d.q.subtract(g.ONE),l=i.multiply(j);if(0===l.gcd(d.ee).compareTo(g.ONE)){d.n=d.p.multiply(d.q),d.d=d.ee.modInverse(l),d.dmp1=d.d.mod(i),d.dmq1=d.d.mod(j),d.u=d.p.modInverse(d.q);break}}return d}this.encrypt=b,this.decrypt=a,this.verify=i,this.sign=f,this.generate=l,this.keyObject=k}var g=a("./jsbn.js"),h=a("../../util.js"),i=a("../random.js"),j=a("../../config"),k=g.ZERO,l=g.ZERO;b.exports=f},{"../../config":4,"../../util.js":61,"../random.js":26,"./jsbn.js":24}],26:[function(a,b){function c(){this.buffer=null,this.size=null}var d=a("../type/mpi.js"),e=null;"undefined"==typeof window&&(e=a("crypto")),b.exports={getRandomBytes:function(a){for(var b="",c=0;a>c;c++)b+=String.fromCharCode(this.getSecureRandomOctet());return b},getSecureRandom:function(a,b){for(var c=this.getSecureRandomUint(),d=(b-a).toString(2).length;(c&Math.pow(2,d)-1)>b-a;)c=this.getSecureRandomUint();return a+Math.abs(c&Math.pow(2,d)-1)},getSecureRandomOctet:function(){var a=new Uint8Array(1);return this.getRandomValues(a),a[0]},getSecureRandomUint:function(){var a=new Uint8Array(4),b=new DataView(a.buffer);return this.getRandomValues(a),b.getUint32(0)},getRandomValues:function(a){if(!(a instanceof Uint8Array))throw new Error("Invalid type: buf not an Uint8Array");if("undefined"!=typeof window&&window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(a);else if("undefined"!=typeof window&&"object"==typeof window.msCrypto&&"function"==typeof window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(a);else if(e){var b=e.randomBytes(a.length);a.set(b)}else{if(!this.randomBuffer.buffer)throw new Error("No secure random number generator available.");this.randomBuffer.get(a)}},getRandomBigInteger:function(a){if(1>a)throw new Error("Illegal parameter value: bits < 1");var b=Math.floor((a+7)/8),c=this.getRandomBytes(b);a%8>0&&(c=String.fromCharCode(Math.pow(2,a%8)-1&c.charCodeAt(0))+c.substring(1));var e=new d;return e.fromBytes(c),e.toBigInteger()},getRandomBigIntegerInRange:function(a,b){if(b.compareTo(a)<=0)throw new Error("Illegal parameter value: max <= min");for(var c=b.subtract(a),d=this.getRandomBigInteger(c.bitLength());d>c;)d=this.getRandomBigInteger(c.bitLength());return a.add(d)},randomBuffer:new c},c.prototype.init=function(a){this.buffer=new Uint8Array(a),this.size=0},c.prototype.set=function(a){if(!this.buffer)throw new Error("RandomBuffer is not initialized");if(!(a instanceof Uint8Array))throw new Error("Invalid type: buf not an Uint8Array");var b=this.buffer.length-this.size;a.length>b&&(a=a.subarray(0,b)),this.buffer.set(a,this.size),this.size+=a.length},c.prototype.get=function(a){if(!this.buffer)throw new Error("RandomBuffer is not initialized");if(!(a instanceof Uint8Array))throw new Error("Invalid type: buf not an Uint8Array");if(this.size>16)+String.fromCharCode(b>>8&255)+String.fromCharCode(255&b);return m.encode(c)}function f(a,b){var c=e(a),d=b;return c[0]==d[0]&&c[1]==d[1]&&c[2]==d[2]&&c[3]==d[3]}function g(a){for(var b=11994318,c=0;a.length-c>16;)b=b<<8^p[255&(b>>16^a.charCodeAt(c))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+1))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+2))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+3))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+4))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+5))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+6))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+7))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+8))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+9))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+10))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+11))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+12))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+13))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+14))],b=b<<8^p[255&(b>>16^a.charCodeAt(c+15))],c+=16;for(var d=c;d>16^a.charCodeAt(c++))];return 16777215&b}function h(a){var b=/^\s*\n/m,c="",d=a,e=b.exec(a);if(null===e)throw new Error("Mandatory blank line missing between armor headers and armor data");return c=a.slice(0,e.index),d=a.slice(e.index+e[0].length),c=c.split("\n"),c.pop(),{headers:c,body:d}}function i(a){for(var b=0;bd;d++)c=a.charCodeAt(d),0===h?(f+=e.charAt(c>>2&63),b=(3&c)<<4):1==h?(f+=e.charAt(b|c>>4&15),b=(15&c)<<2):2==h&&(f+=e.charAt(b|c>>6&3),g+=1,g%60===0&&(f+="\n"),f+=e.charAt(63&c)),g+=1,g%60===0&&(f+="\n"),h+=1,3==h&&(h=0);return h>0&&(f+=e.charAt(b),g+=1,g%60===0&&(f+="\n"),f+="=",g+=1),1==h&&(g%60===0&&(f+="\n"),f+="="),f}function d(a){var b,c,d="",f=0,g=0,h=a.length;for(c=0;h>c;c++)b=e.indexOf(a.charAt(c)),b>=0&&(f&&(d+=String.fromCharCode(g|b>>6-f&255)),f=f+2&7,g=b<>c,d.count++})}var e={prio:0,algo:r.encryption_cipher};for(var f in b)try{f!==p.symmetric.plaintext&&f!==p.symmetric.idea&&p.read(p.symmetric,f)&&b[f].count===a.length&&b[f].prio>e.prio&&(e=b[f])}catch(g){}return e.algo}var o=a("./packet"),p=a("./enums.js"),q=a("./encoding/armor.js"),r=a("./config"),s=a("./util");d.prototype.packetlist2structure=function(a){for(var b,c,d,e=0;ethis.primaryKey.created.getTime()+24*this.primaryKey.expirationTimeV3*3600*1e3)return p.keyStatus.expired;for(var a=!1,b=0;bthis.primaryKey.created.getTime()+1e3*c.selfCertificate.keyExpirationTime?p.keyStatus.expired:p.keyStatus.valid:p.keyStatus.invalid},d.prototype.getExpirationTime=function(){if(3==this.primaryKey.version)return h(this.primaryKey);if(4==this.primaryKey.version){var a=this.getPrimaryUser();return a?h(this.primaryKey,a.selfCertificate):null}},d.prototype.getPrimaryUser=function(){for(var a=[],b=0;bb.isPrimaryUserID?-1:a.isPrimaryUserIDb.created?-1:a.createdb?-1:b>a?1:0}),c=0;cthis.subKey.created.getTime()+24*this.subKey.expirationTimeV3*3600*1e3?p.keyStatus.expired:this.bindingSignature?this.bindingSignature.isExpired()?p.keyStatus.expired:this.bindingSignature.verified||this.bindingSignature.verify(a,{key:a,bind:this.subKey})?4==this.subKey.version&&this.bindingSignature.keyNeverExpires===!1&&Date.now()>this.subKey.created.getTime()+1e3*this.bindingSignature.keyExpirationTime?p.keyStatus.expired:p.keyStatus.valid:p.keyStatus.invalid:p.keyStatus.invalid},k.prototype.getExpirationTime=function(){return h(this.subKey,this.bindingSignature)},k.prototype.update=function(a,b){if(a.verify(b)!==p.keyStatus.invalid){if(this.subKey.getFingerprint()!==a.subKey.getFingerprint())throw new Error("SubKey update method: fingerprints of subkeys not equal");this.subKey.tag===p.packet.publicSubkey&&a.subKey.tag===p.packet.secretSubkey&&(this.subKey=a.subKey),!this.bindingSignature&&a.bindingSignature&&(a.bindingSignature.verified||a.bindingSignature.verify(b,{key:b,bind:this.subKey}))&&(this.bindingSignature=a.bindingSignature),this.revocationSignature||!a.revocationSignature||a.revocationSignature.isExpired()||!a.revocationSignature.verified&&!a.revocationSignature.verify(b,{key:b,bind:this.subKey})||(this.revocationSignature=a.revocationSignature)}},c.Key=d,c.readArmored=l,c.generate=m,c.getPreferredSymAlgo=n},{"./config":4,"./encoding/armor.js":28,"./enums.js":30,"./packet":40,"./util":61}],33:[function(a,b){b.exports=a("./keyring.js"),b.exports.localstore=a("./localstore.js") +},{"./keyring.js":34,"./localstore.js":35}],34:[function(a,b){function c(b){this.storeHandler=b||new(a("./localstore.js")),this.publicKeys=new d(this.storeHandler.loadPublic()),this.privateKeys=new d(this.storeHandler.loadPrivate())}function d(a){this.keys=a}function e(a,b){a=a.toLowerCase();for(var c=b.getUserIds(),d=0;d")[0].trim().toLowerCase(),keyEmail==a)return!0;return!1}function f(a,b){return 16===a.length?a===b.getKeyId().toHex():a===b.getFingerprint()}{var g=(a("../enums.js"),a("../key.js"));a("../util.js")}b.exports=c,c.prototype.store=function(){this.storeHandler.storePublic(this.publicKeys.keys),this.storeHandler.storePrivate(this.privateKeys.keys)},c.prototype.clear=function(){this.publicKeys.keys=[],this.privateKeys.keys=[]},c.prototype.getKeysForId=function(a,b){var c=[];return c=c.concat(this.publicKeys.getForId(a,b)||[]),c=c.concat(this.privateKeys.getForId(a,b)||[]),c.length?c:null},c.prototype.removeKeysForId=function(a){var b=[];return b=b.concat(this.publicKeys.removeForId(a)||[]),b=b.concat(this.privateKeys.removeForId(a)||[]),b.length?b:null},c.prototype.getAllKeys=function(){return this.publicKeys.keys.concat(this.privateKeys.keys)},d.prototype.getForAddress=function(a){for(var b=[],c=0;c=0;e--){var m=new h.Signature;if(m.signatureType=g,m.hashAlgorithm=k.prefer_hash_algorithm,m.publicKeyAlgorithm=l.algorithm,!l.isDecrypted)throw new Error("Private key is not decrypted.");m.sign(l,c),b.push(m)}return new d(b)},d.prototype.verify=function(a){var b=[],c=this.unwrapCompressed(),d=c.packets.filterByTag(i.packet.literal);if(1!==d.length)throw new Error("Can only verify message with one literal data packet.");var e=c.packets.filterByTag(i.packet.signature);return a.forEach(function(a){for(var c=0;ce?(d=a.charCodeAt(0),b=1):255>e?(d=(a.charCodeAt(0)-192<<8)+a.charCodeAt(1)+192,b=2):255==e&&(d=c.readNumber(a.substr(1,4)),b=5),{len:d,offset:b}},writeSimpleLength:function(a){var b="";return 192>a?b+=String.fromCharCode(a):a>191&&8384>a?(b+=String.fromCharCode((a-192>>8)+192),b+=String.fromCharCode(a-192&255)):(b+=String.fromCharCode(255),b+=c.writeNumber(a,4)),b},writeHeader:function(a,b){var c="";return c+=String.fromCharCode(192|a),c+=this.writeSimpleLength(b)},writeOldHeader:function(a,b){var d="";return 256>b?(d+=String.fromCharCode(128|a<<2),d+=String.fromCharCode(b)):65536>b?(d+=String.fromCharCode(128|a<<2|1),d+=c.writeNumber(b,2)):(d+=String.fromCharCode(128|a<<2|2),d+=c.writeNumber(b,4)),d},read:function(a,b,d){if(null===a||a.length<=b||a.substring(b).length<2||0===(128&a.charCodeAt(b)))throw new Error("Error during parsing. This message / key is probably not containing a valid OpenPGP format.");var e,f=b,g=-1,h=-1;h=0,0!==(64&a.charCodeAt(f))&&(h=1);var i;h?g=63&a.charCodeAt(f):(g=(63&a.charCodeAt(f))>>2,i=3&a.charCodeAt(f)),f++;var j=null,k=-1;if(h)if(a.charCodeAt(f)<192)e=a.charCodeAt(f++),c.print_debug("1 byte length:"+e);else if(a.charCodeAt(f)>=192&&a.charCodeAt(f)<224)e=(a.charCodeAt(f++)-192<<8)+a.charCodeAt(f++)+192,c.print_debug("2 byte length:"+e);else if(a.charCodeAt(f)>223&&a.charCodeAt(f)<255){e=1<<(31&a.charCodeAt(f++)),c.print_debug("4 byte length:"+e);var l=f+e;j=a.substring(f,f+e);for(var m;;){if(a.charCodeAt(l)<192){m=a.charCodeAt(l++),e+=m,j+=a.substring(l,l+m),l+=m;break}if(a.charCodeAt(l)>=192&&a.charCodeAt(l)<224){m=(a.charCodeAt(l++)-192<<8)+a.charCodeAt(l++)+192,e+=m,j+=a.substring(l,l+m),l+=m;break}if(!(a.charCodeAt(l)>223&&a.charCodeAt(l)<255)){l++,m=a.charCodeAt(l++)<<24|a.charCodeAt(l++)<<16|a[l++].charCodeAt()<<8|a.charCodeAt(l++),j+=a.substring(l,l+m),e+=m,l+=m;break}m=1<<(31&a.charCodeAt(l++)),e+=m,j+=a.substring(l,l+m),l+=m}k=l-f}else f++,e=a.charCodeAt(f++)<<24|a.charCodeAt(f++)<<16|a.charCodeAt(f++)<<8|a.charCodeAt(f++);else switch(i){case 0:e=a.charCodeAt(f++);break;case 1:e=a.charCodeAt(f++)<<8|a.charCodeAt(f++);break;case 2:e=a.charCodeAt(f++)<<24|a.charCodeAt(f++)<<16|a.charCodeAt(f++)<<8|a.charCodeAt(f++);break;default:e=d}return-1==k&&(k=e),null===j&&(j=a.substring(f,f+k)),{tag:g,packet:j,offset:f+k}}}},{"../enums.js":30,"../util.js":61}],45:[function(a,b){function c(){this.length=0}b.exports=c;var d=a("./packet.js"),e=a("./all_packets.js"),f=a("../enums.js");c.prototype.read=function(a){for(var b=0;be;e++)d.push(this[e]);return d},c.prototype.concat=function(a){if(a)for(var b=0;bj&&if.length)throw new Error("Error reading MPI @:"+i);return i+6}throw new Error("Version "+this.version+" of the key packet is unsupported.")},c.prototype.readPublicKey=c.prototype.read,c.prototype.write=function(){var a=String.fromCharCode(this.version);a+=d.writeDate(this.created),3==this.version&&(a+=d.writeNumber(this.expirationTimeV3,2)),a+=String.fromCharCode(g.write(g.publicKey,this.algorithm));for(var b=h.getPublicMpiCount(this.algorithm),c=0;b>c;c++)a+=this.mpi[c].write();return a},c.prototype.writePublicKey=c.prototype.write,c.prototype.writeOld=function(){var a=this.writePublicKey();return String.fromCharCode(153)+d.writeNumber(a.length,2)+a},c.prototype.getKeyId=function(){return this.keyid?this.keyid:(this.keyid=new f,4==this.version?this.keyid.read(d.hex2bin(this.getFingerprint()).substr(12,8)):3==this.version&&this.keyid.read(this.mpi[0].write().substr(-8)),this.keyid)},c.prototype.getFingerprint=function(){if(this.fingerprint)return this.fingerprint;var a="";if(4==this.version)a=this.writeOld(),this.fingerprint=h.hash.sha1(a);else if(3==this.version){for(var b=h.getPublicMpiCount(this.algorithm),c=0;b>c;c++)a+=this.mpi[c].toBytes();this.fingerprint=h.hash.md5(a)}return this.fingerprint=d.hexstrdump(this.fingerprint),this.fingerprint},c.prototype.getBitSize=function(){return 8*this.mpi[0].byteLength()},c.prototype.postCloneTypeFix=function(){for(var a=0;ad;d++){var e=new f;b+=e.read(a.substr(b)),this.encrypted.push(e)}},c.prototype.write=function(){var a=String.fromCharCode(this.version);a+=this.publicKeyId.write(),a+=String.fromCharCode(g.write(g.publicKey,this.publicKeyAlgorithm));for(var b=0;bo&&kc;){var d=f.readSimpleLength(a.substr(c));c+=d.offset,this.read_sub_packet(a.substr(c,d.len)),c+=d.len}return c}var c=0;switch(this.version=a.charCodeAt(c++),this.version){case 3:5!=a.charCodeAt(c++)&&e.print_debug("packet/signature.js\ninvalid One-octet length of following hashed material.MUST be 5. @:"+(c-1));var d=c;this.signatureType=a.charCodeAt(c++),this.created=e.readDate(a.substr(c,4)),c+=4,this.signatureData=a.substring(d,c),this.issuerKeyId.read(a.substring(c,c+8)),c+=8,this.publicKeyAlgorithm=a.charCodeAt(c++),this.hashAlgorithm=a.charCodeAt(c++);break;case 4:this.signatureType=a.charCodeAt(c++),this.publicKeyAlgorithm=a.charCodeAt(c++),this.hashAlgorithm=a.charCodeAt(c++),c+=b.call(this,a.substr(c),!0),this.signatureData=a.substr(0,c);var g=c;c+=b.call(this,a.substr(c),!1),this.unhashedSubpackets=a.substr(g,c-g);break;default:throw new Error("Version "+this.version+" of the signature is unsupported.")}this.signedHashValue=a.substr(c,2),c+=2,this.signature=a.substr(c)},c.prototype.write=function(){var a="";switch(this.version){case 3:a+=String.fromCharCode(3),a+=String.fromCharCode(5),a+=this.signatureData,a+=this.issuerKeyId.write(),a+=String.fromCharCode(this.publicKeyAlgorithm),a+=String.fromCharCode(this.hashAlgorithm);break;case 4:a+=this.signatureData,a+=this.unhashedSubpackets?this.unhashedSubpackets:e.writeNumber(0,2)}return a+=this.signedHashValue+this.signature},c.prototype.sign=function(a,b){var c=g.write(g.signature,this.signatureType),d=g.write(g.publicKey,this.publicKeyAlgorithm),e=g.write(g.hash,this.hashAlgorithm),f=String.fromCharCode(4);f+=String.fromCharCode(c),f+=String.fromCharCode(d),f+=String.fromCharCode(e),this.issuerKeyId=a.getKeyId(),f+=this.write_all_sub_packets(),this.signatureData=f;var i=this.calculateTrailer(),j=this.toSign(c,b)+this.signatureData+i,k=h.hash.digest(e,j);this.signedHashValue=k.substr(0,2),this.signature=h.signature.sign(e,d,a.mpi,j)},c.prototype.write_all_sub_packets=function(){var a=g.signatureSubpacket,b="",c="";if(null!==this.created&&(b+=d(a.signature_creation_time,e.writeDate(this.created))),null!==this.signatureExpirationTime&&(b+=d(a.signature_expiration_time,e.writeNumber(this.signatureExpirationTime,4))),null!==this.exportable&&(b+=d(a.exportable_certification,String.fromCharCode(this.exportable?1:0))),null!==this.trustLevel&&(c=String.fromCharCode(this.trustLevel)+String.fromCharCode(this.trustAmount),b+=d(a.trust_signature,c)),null!==this.regularExpression&&(b+=d(a.regular_expression,this.regularExpression)),null!==this.revocable&&(b+=d(a.revocable,String.fromCharCode(this.revocable?1:0))),null!==this.keyExpirationTime&&(b+=d(a.key_expiration_time,e.writeNumber(this.keyExpirationTime,4))),null!==this.preferredSymmetricAlgorithms&&(c=e.bin2str(this.preferredSymmetricAlgorithms),b+=d(a.preferred_symmetric_algorithms,c)),null!==this.revocationKeyClass&&(c=String.fromCharCode(this.revocationKeyClass),c+=String.fromCharCode(this.revocationKeyAlgorithm),c+=this.revocationKeyFingerprint,b+=d(a.revocation_key,c)),this.issuerKeyId.isNull()||(b+=d(a.issuer,this.issuerKeyId.write())),null!==this.notation)for(var f in this.notation)if(this.notation.hasOwnProperty(f)){var h=this.notation[f];c=String.fromCharCode(128),c+=String.fromCharCode(0),c+=String.fromCharCode(0),c+=String.fromCharCode(0),c+=e.writeNumber(f.length,2),c+=e.writeNumber(h.length,2),c+=f+h,b+=d(a.notation_data,c)}return null!==this.preferredHashAlgorithms&&(c=e.bin2str(this.preferredHashAlgorithms),b+=d(a.preferred_hash_algorithms,c)),null!==this.preferredCompressionAlgorithms&&(c=e.bin2str(this.preferredCompressionAlgorithms),b+=d(a.preferred_compression_algorithms,c)),null!==this.keyServerPreferences&&(c=e.bin2str(this.keyServerPreferences),b+=d(a.key_server_preferences,c)),null!==this.preferredKeyServer&&(b+=d(a.preferred_key_server,this.preferredKeyServer)),null!==this.isPrimaryUserID&&(b+=d(a.primary_user_id,String.fromCharCode(this.isPrimaryUserID?1:0))),null!==this.policyURI&&(b+=d(a.policy_uri,this.policyURI)),null!==this.keyFlags&&(c=e.bin2str(this.keyFlags),b+=d(a.key_flags,c)),null!==this.signersUserId&&(b+=d(a.signers_user_id,this.signersUserId)),null!==this.reasonForRevocationFlag&&(c=String.fromCharCode(this.reasonForRevocationFlag),c+=this.reasonForRevocationString,b+=d(a.reason_for_revocation,c)),null!==this.features&&(c=e.bin2str(this.features),b+=d(a.features,c)),null!==this.signatureTargetPublicKeyAlgorithm&&(c=String.fromCharCode(this.signatureTargetPublicKeyAlgorithm),c+=String.fromCharCode(this.signatureTargetHashAlgorithm),c+=this.signatureTargetHash,b+=d(a.signature_target,c)),null!==this.embeddedSignature&&(b+=d(a.embedded_signature,this.embeddedSignature.write())),b=e.writeNumber(b.length,2)+b +},c.prototype.read_sub_packet=function(a){function b(a,b){this[a]=[];for(var c=0;c0&&4>d?k=1:17==d&&(k=2);for(var l=[],m=0,n=0;k>n;n++)l[n]=new i,m+=l[n].read(this.signature.substr(m));return this.verified=h.signature.verify(d,e,l,a.mpi,f+this.signatureData+j),this.verified},c.prototype.isExpired=function(){return this.signatureNeverExpires?!1:Date.now()>this.created.getTime()+1e3*this.signatureExpirationTime},c.prototype.postCloneTypeFix=function(){this.issuerKeyId=j.fromClone(this.issuerKeyId)}},{"../crypto":19,"../enums.js":30,"../type/keyid.js":58,"../type/mpi.js":59,"../util.js":61,"./packet.js":44}],52:[function(a,b){function c(){this.tag=e.packet.symEncryptedIntegrityProtected,this.encrypted=null,this.modification=!1,this.packets=null}b.exports=c;var d=(a("../util.js"),a("../crypto")),e=a("../enums.js");c.prototype.read=function(a){var b=a.charCodeAt(0);if(1!=b)throw new Error("Invalid packet version.");this.encrypted=a.substr(1)},c.prototype.write=function(){return String.fromCharCode(1)+this.encrypted},c.prototype.encrypt=function(a,b){var c=this.packets.write(),e=d.getPrefixRandom(a),f=e+e.charAt(e.length-2)+e.charAt(e.length-1),g=c;g+=String.fromCharCode(211),g+=String.fromCharCode(20),g+=d.hash.sha1(f+g),this.encrypted=d.cfb.encrypt(e,a,g,b,!1).substring(0,f.length+g.length)},c.prototype.decrypt=function(a,b){var c=d.cfb.decrypt(a,b,this.encrypted,!1);this.hash=d.hash.sha1(d.cfb.mdc(a,b,this.encrypted)+c.substring(0,c.length-20));var e=c.substr(c.length-20,20);if(this.hash!=e)throw new Error("Modification detected.");this.packets.read(c.substr(0,c.length-22))}},{"../crypto":19,"../enums.js":30,"../util.js":61}],53:[function(a,b){function c(){this.tag=e.packet.symEncryptedSessionKey,this.sessionKeyEncryptionAlgorithm=null,this.sessionKeyAlgorithm="aes256",this.encrypted=null,this.s2k=new d}var d=a("../type/s2k.js"),e=a("../enums.js"),f=a("../crypto");b.exports=c,c.prototype.read=function(a){this.version=a.charCodeAt(0);var b=e.read(e.symmetric,a.charCodeAt(1)),c=this.s2k.read(a.substr(2)),d=c+2;d>4)+a},c.prototype.read=function(a){var b=0;switch(this.type=d.read(d.s2k,a.charCodeAt(b++)),this.algorithm=d.read(d.hash,a.charCodeAt(b++)),this.type){case"simple":break;case"salted":this.salt=a.substr(b,8),b+=8;break;case"iterated":this.salt=a.substr(b,8),b+=8,this.c=a.charCodeAt(b++);break;case"gnu":if("GNU"!=a.substr(b,3))throw new Error("Unknown s2k type.");b+=3;var c=1e3+a.charCodeAt(b++);if(1001!=c)throw new Error("Unknown s2k gnu protection mode.");this.type=c;break;default:throw new Error("Unknown s2k type.")}return b},c.prototype.write=function(){var a=String.fromCharCode(d.write(d.s2k,this.type));switch(a+=String.fromCharCode(d.write(d.hash,this.algorithm)),this.type){case"simple":break;case"salted":a+=this.salt;break;case"iterated":a+=this.salt,a+=String.fromCharCode(this.c)}return a},c.prototype.produce_key=function(a,b){function c(b,c){var e=d.write(d.hash,c.algorithm);switch(c.type){case"simple":return f.hash.digest(e,b+a);case"salted":return f.hash.digest(e,b+c.salt+a);case"iterated":var g=[],h=c.get_count();for(data=c.salt+a;g.length*data.lengthh&&(g=g.substr(0,h)),f.hash.digest(e,b+g)}}a=e.encode_utf8(a);for(var g="",h="";g.length<=b;)g+=c(h,this),h+=String.fromCharCode(0);return g.substr(0,b)},b.exports.fromClone=function(a){var b=new c;return this.algorithm=a.algorithm,this.type=a.type,this.c=a.c,this.salt=a.salt,b}},{"../crypto":19,"../enums.js":30,"../util.js":61}],61:[function(a,b){var c=a("./config");b.exports={readNumber:function(a){for(var b=0,c=0;cd;d++)c+=String.fromCharCode(a>>8*(b-d-1)&255);return c},readDate:function(a){var b=this.readNumber(a),c=new Date;return c.setTime(1e3*b),c},writeDate:function(a){var b=Math.round(a.getTime()/1e3);return this.writeNumber(b,4)},emailRegEx:/^[+a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]{2,6}$/,hexdump:function(a){for(var b,c=[],d=a.length,e=0,f=0;d>e;){for(b=a.charCodeAt(e++).toString(16);b.length<2;)b="0"+b;c.push(" "+b),f++,f%32===0&&c.push("\n ")}return c.join("")},hexstrdump:function(a){if(null===a)return"";for(var b,c=[],d=a.length,e=0;d>e;){for(b=a.charCodeAt(e++).toString(16);b.length<2;)b="0"+b;c.push(""+b)}return c.join("")},hex2bin:function(a){for(var b="",c=0;ce;){for(b=a[e++].toString(16);b.length<2;)b="0"+b;c.push(""+b)}return c.join("")},encode_utf8:function(a){return unescape(encodeURIComponent(a))},decode_utf8:function(a){if("string"!=typeof a)throw new Error('Parameter "utf8" is not of type string');try{return decodeURIComponent(escape(a))}catch(b){return a}},bin2str:function(a){for(var b=[],c=0;c=0;d--)c[d]>>=b%8,d>0&&(c[d]|=c[d-1]<<8-b%8&255);return util.bin2str(c)},get_hashAlgorithmString:function(a){switch(a){case 1:return"MD5";case 2:return"SHA1";case 3:return"RIPEMD160";case 8:return"SHA256";case 9:return"SHA384";case 10:return"SHA512";case 11:return"SHA224"}return"unknown"}}},{"./config":4}],62:[function(a,b){function c(a){this.worker=new Worker(a||"openpgp.worker.js"),this.worker.onmessage=this.onMessage.bind(this),this.worker.onerror=function(a){throw new Error("Unhandled error in openpgp worker: "+a.message+" ("+a.filename+":"+a.lineno+")")},this.seedRandom(h),this.tasks=[]}var d=a("../crypto"),e=a("../packet"),f=a("../key.js"),g=a("../type/keyid.js"),h=(a("../enums.js"),5e4),i=2e4;c.prototype.onMessage=function(a){var b=a.data;switch(b.event){case"method-return":this.tasks.shift()(b.err?new Error(b.err):null,b.data);break;case"request-seed":this.seedRandom(i);break;default:throw new Error("Unknown Worker Event.")}},c.prototype.seedRandom=function(a){var b=this.getRandomBuffer(a);this.worker.postMessage({event:"seed-random",buf:b})},c.prototype.getRandomBuffer=function(a){if(!a)return null;var b=new Uint8Array(a);return d.random.getRandomValues(b),b},c.prototype.terminate=function(){this.worker.terminate()},c.prototype.encryptMessage=function(a,b,c){a=a.map(function(a){return a.toPacketlist()}),this.worker.postMessage({event:"encrypt-message",keys:a,text:b}),this.tasks.push(c)},c.prototype.signAndEncryptMessage=function(a,b,c,d){a=a.map(function(a){return a.toPacketlist()}),b=b.toPacketlist(),this.worker.postMessage({event:"sign-and-encrypt-message",publicKeys:a,privateKey:b,text:c}),this.tasks.push(d)},c.prototype.decryptMessage=function(a,b,c){a=a.toPacketlist(),this.worker.postMessage({event:"decrypt-message",privateKey:a,message:b}),this.tasks.push(c)},c.prototype.decryptAndVerifyMessage=function(a,b,c,d){a=a.toPacketlist(),b=b.map(function(a){return a.toPacketlist()}),this.worker.postMessage({event:"decrypt-and-verify-message",privateKey:a,publicKeys:b,message:c}),this.tasks.push(function(a,b){b&&(b.signatures=b.signatures.map(function(a){return a.keyid=g.fromClone(a.keyid),a})),d(a,b)})},c.prototype.signClearMessage=function(a,b,c){a=a.map(function(a){return a.toPacketlist()}),this.worker.postMessage({event:"sign-clear-message",privateKeys:a,text:b}),this.tasks.push(c)},c.prototype.verifyClearSignedMessage=function(a,b,c){a=a.map(function(a){return a.toPacketlist()}),this.worker.postMessage({event:"verify-clear-signed-message",publicKeys:a,message:b}),this.tasks.push(function(a,b){b&&(b.signatures=b.signatures.map(function(a){return a.keyid=g.fromClone(a.keyid),a})),c(a,b)})},c.prototype.generateKeyPair=function(a,b){this.worker.postMessage({event:"generate-key-pair",options:a}),this.tasks.push(function(a,c){if(c){var d=e.List.fromStructuredClone(c.key);c.key=new f.Key(d)}b(a,c)})},c.prototype.decryptKey=function(a,b,c){a=a.toPacketlist(),this.worker.postMessage({event:"decrypt-key",privateKey:a,password:b}),this.tasks.push(function(a,b){if(b){var d=e.List.fromStructuredClone(b);b=new f.Key(d)}c(a,b)})},c.prototype.decryptKeyPacket=function(a,b,c,d){a=a.toPacketlist(),this.worker.postMessage({event:"decrypt-key-packet",privateKey:a,keyIds:b,password:c}),this.tasks.push(function(a,b){if(b){var c=e.List.fromStructuredClone(b);b=new f.Key(c)}d(a,b)})},b.exports=c},{"../crypto":19,"../enums.js":30,"../key.js":32,"../packet":40,"../type/keyid.js":58}]},{},[31])(31)}); \ No newline at end of file diff --git a/src/lib/openpgp/openpgp.worker.min.js b/src/lib/openpgp/openpgp.worker.min.js index 9b631b0..662ee1e 100644 --- a/src/lib/openpgp/openpgp.worker.min.js +++ b/src/lib/openpgp/openpgp.worker.min.js @@ -1 +1 @@ -/*! OpenPGPjs.org this is LGPL licensed code, see LICENSE/our website for more information.- v0.5.1 - 2014-04-03 */!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g PGP Key ID - {{keyId}} + {{keyId}} (Revoke key) PGP Fingerprint diff --git a/src/tpl/desktop.html b/src/tpl/desktop.html index 88ec5d9..c85aa4d 100644 --- a/src/tpl/desktop.html +++ b/src/tpl/desktop.html @@ -31,6 +31,10 @@ + + diff --git a/src/tpl/login-privatekey-download.html b/src/tpl/login-privatekey-download.html new file mode 100644 index 0000000..c543347 --- /dev/null +++ b/src/tpl/login-privatekey-download.html @@ -0,0 +1,30 @@ + diff --git a/src/tpl/navigation.html b/src/tpl/navigation.html index a054a3a..637474c 100644 --- a/src/tpl/navigation.html +++ b/src/tpl/navigation.html @@ -17,6 +17,7 @@ diff --git a/src/tpl/privatekey-upload.html b/src/tpl/privatekey-upload.html new file mode 100644 index 0000000..c0366de --- /dev/null +++ b/src/tpl/privatekey-upload.html @@ -0,0 +1,46 @@ + \ No newline at end of file diff --git a/test/new-unit/devicestorage-dao-test.js b/test/new-unit/devicestorage-dao-test.js deleted file mode 100644 index f593e39..0000000 --- a/test/new-unit/devicestorage-dao-test.js +++ /dev/null @@ -1,105 +0,0 @@ -define(function(require) { - 'use strict'; - - var LawnchairDAO = require('js/dao/lawnchair-dao'), - DeviceStorageDAO = require('js/dao/devicestorage-dao'), - expect = chai.expect; - - var testUser = 'test@example.com'; - - describe('Device Storage DAO unit tests', function() { - - var storageDao, lawnchairDaoStub; - - beforeEach(function() { - lawnchairDaoStub = sinon.createStubInstance(LawnchairDAO); - storageDao = new DeviceStorageDAO(lawnchairDaoStub); - }); - - afterEach(function() {}); - - describe('init', function() { - it('should work', function(done) { - lawnchairDaoStub.init.yields(); - - storageDao.init(testUser, function(err) { - expect(err).to.not.exist; - expect(lawnchairDaoStub.init.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('store list', function() { - it('should fail', function(done) { - var list = [{}]; - - storageDao.storeList(list, '', function(err) { - expect(err).to.exist; - done(); - }); - }); - - it('should work with empty list', function(done) { - var list = []; - - storageDao.storeList(list, 'email', function(err) { - expect(err).to.not.exist; - done(); - }); - }); - - it('should work', function(done) { - lawnchairDaoStub.batch.yields(); - - var list = [{ - foo: 'bar' - }]; - - storageDao.storeList(list, 'email', function(err) { - expect(err).to.not.exist; - expect(lawnchairDaoStub.batch.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('remove list', function() { - it('should work', function(done) { - lawnchairDaoStub.removeList.yields(); - - storageDao.removeList('email', function(err) { - expect(err).to.not.exist; - expect(lawnchairDaoStub.removeList.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('list items', function() { - it('should work', function(done) { - lawnchairDaoStub.list.yields(); - - storageDao.listItems('email', 0, null, function(err) { - expect(err).to.not.exist; - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('clear', function() { - it('should work', function(done) { - lawnchairDaoStub.clear.yields(); - - storageDao.clear(function(err) { - expect(err).to.not.exist; - expect(lawnchairDaoStub.clear.calledOnce).to.be.true; - done(); - }); - }); - }); - - }); - -}); \ No newline at end of file diff --git a/test/new-unit/email-dao-test.js b/test/new-unit/email-dao-test.js deleted file mode 100644 index 900523c..0000000 --- a/test/new-unit/email-dao-test.js +++ /dev/null @@ -1,1909 +0,0 @@ -define(function(require) { - 'use strict'; - - var EmailDAO = require('js/dao/email-dao'), - KeychainDAO = require('js/dao/keychain-dao'), - ImapClient = require('imap-client'), - PgpMailer = require('pgpmailer'), - PgpBuilder = require('pgpbuilder'), - PGP = require('js/crypto/pgp'), - DeviceStorageDAO = require('js/dao/devicestorage-dao'), - mailreader = require('mailreader'), - appcfg = require('js/app-config'), - str = appcfg.string, - cfg = appcfg.config, - expect = chai.expect; - - - describe('Email DAO unit tests', function() { - // show the stack trace when an error occurred - chai.Assertion.includeStack = true; - - // SUT - var dao; - - // mocks - var keychainStub, imapClientStub, pgpMailerStub, pgpBuilderStub, pgpStub, devicestorageStub, parseStub; - - // config - var emailAddress, passphrase, asymKeySize, account; - - // test data - var folders, inboxFolder, sentFolder, draftsFolder, outboxFolder, trashFolder, mockKeyPair; - - beforeEach(function() { - // - // test data - // - emailAddress = 'asdf@asdf.com'; - passphrase = 'asdf'; - asymKeySize = 2048; - - inboxFolder = { - type: 'Inbox', - path: 'INBOX', - messages: [] - }; - - sentFolder = { - type: 'Sent', - path: 'SENT', - messages: [] - }; - - draftsFolder = { - type: 'Drafts', - path: 'DRAFTS', - messages: [] - }; - - outboxFolder = { - type: 'Outbox', - path: 'OUTBOX', - messages: [] - }; - - trashFolder = { - type: 'Trash', - path: 'TRASH', - messages: [] - }; - - folders = [inboxFolder, outboxFolder, trashFolder]; - - account = { - emailAddress: emailAddress, - asymKeySize: asymKeySize, - folders: folders, - online: true - }; - - mockKeyPair = { - publicKey: { - _id: 1234, - userId: emailAddress, - publicKey: 'publicpublicpublicpublic' - }, - privateKey: { - _id: 1234, - userId: emailAddress, - encryptedKey: 'privateprivateprivateprivate' - } - }; - - // - // setup the mocks - // - keychainStub = sinon.createStubInstance(KeychainDAO); - imapClientStub = sinon.createStubInstance(ImapClient); - pgpMailerStub = sinon.createStubInstance(PgpMailer); - pgpBuilderStub = sinon.createStubInstance(PgpBuilder); - pgpStub = sinon.createStubInstance(PGP); - parseStub = sinon.stub(mailreader, 'parse'); - devicestorageStub = sinon.createStubInstance(DeviceStorageDAO); - - // - // setup the SUT - // - dao = new EmailDAO(keychainStub, pgpStub, devicestorageStub, pgpBuilderStub, mailreader); - dao._account = account; - dao._pgpMailer = pgpMailerStub; - dao._imapClient = imapClientStub; - - // - // check configuration - // - expect(dao._keychain).to.equal(keychainStub); - expect(dao._crypto).to.equal(pgpStub); - expect(dao._devicestorage).to.equal(devicestorageStub); - expect(dao._mailreader).to.equal(mailreader); - expect(dao._pgpbuilder).to.equal(pgpBuilderStub); - }); - - afterEach(function() { - mailreader.parse.restore(); - }); - - describe('public API', function() { - describe('#init', function() { - var initFoldersStub; - - beforeEach(function() { - delete dao._account; - initFoldersStub = sinon.stub(dao, '_initFoldersFromDisk'); - }); - - it('should initialize folders and return keypair', function(done) { - keychainStub.getUserKeyPair.withArgs(emailAddress).yieldsAsync(null, mockKeyPair); - initFoldersStub.yieldsAsync(); - - dao.init({ - account: account - }, function(err, keypair) { - expect(err).to.not.exist; - expect(keypair).to.exist; - expect(keychainStub.getUserKeyPair.calledOnce).to.be.true; - expect(initFoldersStub.calledOnce).to.be.true; - - done(); - }); - }); - - it('should fail when keychain errors', function(done) { - keychainStub.getUserKeyPair.yieldsAsync({}); - - dao.init({ - account: account - }, function(err, keypair) { - expect(err).to.exist; - expect(keypair).to.not.exist; - expect(keychainStub.getUserKeyPair.calledOnce).to.be.true; - expect(initFoldersStub.called).to.be.false; - - done(); - }); - }); - }); - - describe('#unlock', function() { - it('should unlock', function(done) { - pgpStub.getKeyParams.returns({ - _id: mockKeyPair.publicKey._id, - userId: emailAddress, - userIds: [{ - emailAddress: emailAddress - }] - }); - - pgpStub.importKeys.withArgs({ - passphrase: passphrase, - privateKeyArmored: mockKeyPair.privateKey.encryptedKey, - publicKeyArmored: mockKeyPair.publicKey.publicKey - }).yieldsAsync(); - pgpStub._privateKey = { - foo: 'bar' - }; - - dao.unlock({ - passphrase: passphrase, - keypair: mockKeyPair - }, function(err) { - expect(err).to.not.exist; - - expect(pgpStub.importKeys.calledOnce).to.be.true; - expect(dao._pgpbuilder._privateKey).to.equal(pgpStub._privateKey); - - done(); - }); - }); - - it('should generate a keypair and unlock', function(done) { - var keypair = { - keyId: 123, - publicKeyArmored: mockKeyPair.publicKey.publicKey, - privateKeyArmored: mockKeyPair.privateKey.encryptedKey - }; - - pgpStub.generateKeys.withArgs({ - emailAddress: emailAddress, - keySize: asymKeySize, - passphrase: passphrase - }).yieldsAsync(null, keypair); - - pgpStub.importKeys.withArgs({ - passphrase: passphrase, - privateKeyArmored: mockKeyPair.privateKey.encryptedKey, - publicKeyArmored: mockKeyPair.publicKey.publicKey - }).yieldsAsync(); - keychainStub.putUserKeyPair.withArgs().yieldsAsync(); - - dao.unlock({ - passphrase: passphrase - }, function(err) { - expect(err).to.not.exist; - - expect(pgpStub.generateKeys.calledOnce).to.be.true; - expect(pgpStub.importKeys.calledOnce).to.be.true; - expect(keychainStub.putUserKeyPair.calledOnce).to.be.true; - - done(); - }); - }); - - it('should fail when persisting fails', function(done) { - var keypair = { - keyId: 123, - publicKeyArmored: 'qwerty', - privateKeyArmored: 'asdfgh' - }; - pgpStub.generateKeys.yieldsAsync(null, keypair); - pgpStub.importKeys.withArgs().yieldsAsync(); - keychainStub.putUserKeyPair.yieldsAsync({}); - - dao.unlock({ - passphrase: passphrase - }, function(err) { - expect(err).to.exist; - - expect(pgpStub.generateKeys.calledOnce).to.be.true; - expect(pgpStub.importKeys.calledOnce).to.be.true; - expect(keychainStub.putUserKeyPair.calledOnce).to.be.true; - - done(); - }); - }); - - it('should fail when import fails', function(done) { - var keypair = { - keyId: 123, - publicKeyArmored: 'qwerty', - privateKeyArmored: 'asdfgh' - }; - - pgpStub.generateKeys.withArgs().yieldsAsync(null, keypair); - pgpStub.importKeys.withArgs().yieldsAsync({}); - - dao.unlock({ - passphrase: passphrase - }, function(err) { - expect(err).to.exist; - - expect(pgpStub.generateKeys.calledOnce).to.be.true; - expect(pgpStub.importKeys.calledOnce).to.be.true; - - done(); - }); - }); - - it('should fail when generation fails', function(done) { - pgpStub.generateKeys.yieldsAsync({}); - - dao.unlock({ - passphrase: passphrase - }, function(err) { - expect(err).to.exist; - - expect(pgpStub.generateKeys.calledOnce).to.be.true; - - done(); - }); - }); - }); - - describe('#openFolder', function() { - it('should open an imap mailbox', function(done) { - imapClientStub.selectMailbox.withArgs({ - path: inboxFolder.path - }).yieldsAsync(); - - dao.openFolder({ - folder: inboxFolder - }, function(err) { - expect(err).to.not.exist; - expect(imapClientStub.selectMailbox.calledOnce).to.be.true; - done(); - }); - }); - - it('should not open the virtual outbox folder in imap', function() { - dao.openFolder({ - folder: outboxFolder - }); - - expect(imapClientStub.selectMailbox.called).to.be.false; - }); - - it('should not do anything in offline mode', function(done) { - account.online = false; - - dao.openFolder({ - folder: inboxFolder - }, function(err) { - expect(err).to.exist; - expect(imapClientStub.selectMailbox.called).to.be.false; - done(); - }); - - }); - }); - - describe('#refreshFolder', function() { - var localListStub, mail; - - beforeEach(function() { - localListStub = sinon.stub(dao, '_localListMessages'); - mail = { - uid: 123, - unread: true - }; - }); - - it('should add messages from disk', function(done) { - localListStub.withArgs({ - folder: inboxFolder - }).yieldsAsync(null, [mail]); - - dao.refreshFolder({ - folder: inboxFolder - }, function(err) { - expect(err).to.not.exist; - expect(inboxFolder.count).to.equal(1); - expect(inboxFolder.messages).to.contain(mail); - - done(); - }); - }); - - it('should not add messages from disk', function(done) { - inboxFolder.messages = [mail]; - localListStub.withArgs({ - folder: inboxFolder - }).yieldsAsync(null, [mail]); - - dao.refreshFolder({ - folder: inboxFolder - }, function(err) { - expect(err).to.not.exist; - expect(inboxFolder.count).to.equal(1); - expect(inboxFolder.messages).to.contain(mail); - - done(); - }); - }); - - it('should remove messages from memory', function(done) { - inboxFolder.messages = [mail]; - localListStub.withArgs({ - folder: inboxFolder - }).yieldsAsync(null, []); - - dao.refreshFolder({ - folder: inboxFolder - }, function(err) { - expect(err).to.not.exist; - expect(inboxFolder.count).to.equal(0); - expect(inboxFolder.messages).to.be.empty; - - done(); - }); - }); - }); - - describe('#fetchMessages', function() { - var imapListStub, imapGetStub, imapDeleteStub, localStoreStub; - var opts, message, validUuid, corruptedUuid, verificationSubject; - var notified; - - beforeEach(function() { - imapListStub = sinon.stub(dao, '_imapListMessages'); - imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); - imapGetStub = sinon.stub(dao, '_getBodyParts'); - localStoreStub = sinon.stub(dao, '_localStoreMessages'); - - opts = { - folder: inboxFolder, - firstUid: 123, - lastUid: 123 - }; - message = { - uid: 123, - subject: 'asdasd', - unread: true, - bodyParts: [] - }; - validUuid = '9A858952-17EE-4273-9E74-D309EAFDFAFB'; - corruptedUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!'; - verificationSubject = "[whiteout] New public key uploaded"; - - notified = false; - dao.onIncomingMessage = function(newMessages) { - expect(newMessages).to.contain(message); - notified = true; - }; - }); - - it('should fetch message downstream', function(done) { - imapListStub.withArgs(opts).yieldsAsync(null, [message]); - - localStoreStub.withArgs({ - folder: inboxFolder, - emails: [message] - }).yieldsAsync(); - - dao.fetchMessages(opts, function(err) { - expect(err).to.not.exist; - expect(inboxFolder.messages).to.contain(message); - expect(notified).to.be.true; - expect(localStoreStub.calledOnce).to.be.true; - expect(imapListStub.calledOnce).to.be.true; - expect(account.busy).to.be.false; - - done(); - }); - }); - - it('should verify verification mails', function(done) { - message.subject = verificationSubject; - - imapListStub.withArgs(opts).yieldsAsync(null, [message]); - - imapGetStub.withArgs({ - folder: inboxFolder, - uid: message.uid, - bodyParts: message.bodyParts - }).yieldsAsync(null, [{ - type: 'text', - content: '' + cfg.cloudUrl + cfg.verificationUrl + validUuid - }]); - - keychainStub.verifyPublicKey.withArgs(validUuid).yieldsAsync(); - - imapDeleteStub.withArgs({ - folder: inboxFolder, - uid: message.uid - }).yieldsAsync(); - - dao.fetchMessages(opts, function(err) { - expect(err).to.not.exist; - expect(inboxFolder.messages).to.not.contain(message); - expect(notified).to.be.false; - expect(imapListStub.calledOnce).to.be.true; - expect(imapGetStub.calledOnce).to.be.true; - expect(keychainStub.verifyPublicKey.calledOnce).to.be.true; - expect(imapDeleteStub.calledOnce).to.be.true; - expect(localStoreStub.called).to.be.false; - done(); - }); - }); - - it('should not verify invalid verification mails', function(done) { - message.subject = verificationSubject; - - imapListStub.withArgs(opts).yieldsAsync(null, [message]); - - imapGetStub.withArgs({ - folder: inboxFolder, - uid: message.uid, - bodyParts: message.bodyParts - }).yieldsAsync(null, [{ - type: 'text', - content: '' + cfg.cloudUrl + cfg.verificationUrl + corruptedUuid - }]); - - localStoreStub.withArgs({ - folder: inboxFolder, - emails: [message] - }).yieldsAsync(); - - dao.fetchMessages(opts, function(err) { - expect(err).to.not.exist; - expect(inboxFolder.messages).to.contain(message); - expect(notified).to.be.true; - expect(imapListStub.calledOnce).to.be.true; - expect(imapGetStub.calledOnce).to.be.true; - expect(keychainStub.verifyPublicKey.called).to.be.false; - expect(imapDeleteStub.called).to.be.false; - expect(localStoreStub.calledOnce).to.be.true; - done(); - }); - }); - - it('should display verification mail when verification failed', function(done) { - message.subject = verificationSubject; - - imapListStub.withArgs(opts).yieldsAsync(null, [message]); - - imapGetStub.withArgs({ - folder: inboxFolder, - uid: message.uid, - bodyParts: message.bodyParts - }).yieldsAsync(null, [{ - type: 'text', - content: '' + cfg.cloudUrl + cfg.verificationUrl + validUuid - }]); - - keychainStub.verifyPublicKey.withArgs(validUuid).yieldsAsync({}); - - localStoreStub.withArgs({ - folder: inboxFolder, - emails: [message] - }).yieldsAsync(); - - - dao.fetchMessages(opts, function(err) { - expect(err).to.not.exist; - expect(inboxFolder.messages).to.contain(message); - expect(notified).to.be.true; - expect(imapListStub.calledOnce).to.be.true; - expect(imapGetStub.calledOnce).to.be.true; - expect(keychainStub.verifyPublicKey.calledOnce).to.be.true; - expect(imapDeleteStub.called).to.be.false; - expect(localStoreStub.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('#deleteMessage', function() { - var imapDeleteStub, localDeleteStub, message; - - beforeEach(function() { - message = { - uid: 1234 - }; - imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); - localDeleteStub = sinon.stub(dao, '_localDeleteMessage'); - inboxFolder.messages = [message]; - outboxFolder.messages = [message]; - }); - - it('should delete from imap, local, memory', function(done) { - var deleteOpts = { - folder: inboxFolder, - uid: message.uid - }; - - imapDeleteStub.withArgs(deleteOpts).yieldsAsync(); - localDeleteStub.withArgs(deleteOpts).yieldsAsync(); - - dao.deleteMessage({ - folder: inboxFolder, - message: message - }, function(err) { - expect(err).to.not.exist; - expect(imapDeleteStub.calledOnce).to.be.true; - expect(localDeleteStub.calledOnce).to.be.true; - expect(inboxFolder.messages).to.not.contain(message); - - done(); - }); - }); - - it('should delete from local, memory', function(done) { - var deleteOpts = { - folder: inboxFolder, - uid: message.uid - }; - - localDeleteStub.withArgs(deleteOpts).yieldsAsync(); - - dao.deleteMessage({ - folder: inboxFolder, - message: message, - localOnly: true - }, function(err) { - expect(err).to.not.exist; - expect(imapDeleteStub.called).to.be.false; - expect(localDeleteStub.calledOnce).to.be.true; - expect(inboxFolder.messages).to.not.contain(message); - - done(); - }); - }); - - it('should delete from outbox from local, memory', function(done) { - var deleteOpts = { - folder: outboxFolder, - uid: message.uid - }; - - localDeleteStub.withArgs(deleteOpts).yieldsAsync(); - - dao.deleteMessage({ - folder: outboxFolder, - message: message - }, function(err) { - expect(err).to.not.exist; - expect(imapDeleteStub.called).to.be.false; - expect(localDeleteStub.calledOnce).to.be.true; - expect(outboxFolder.messages).to.not.contain(message); - - done(); - }); - }); - - it('should fail at delete from local', function(done) { - var deleteOpts = { - folder: inboxFolder, - uid: message.uid - }; - - imapDeleteStub.withArgs(deleteOpts).yieldsAsync(); - localDeleteStub.withArgs(deleteOpts).yieldsAsync({}); - - dao.deleteMessage({ - folder: inboxFolder, - message: message - }, function(err) { - expect(err).to.exist; - expect(imapDeleteStub.calledOnce).to.be.true; - expect(localDeleteStub.calledOnce).to.be.true; - expect(inboxFolder.messages).to.contain(message); - - done(); - }); - }); - - it('should fail at delete from imap', function(done) { - var deleteOpts = { - folder: inboxFolder, - uid: message.uid - }; - - imapDeleteStub.withArgs(deleteOpts).yieldsAsync({}); - - dao.deleteMessage({ - folder: inboxFolder, - message: message - }, function(err) { - expect(err).to.exist; - expect(imapDeleteStub.calledOnce).to.be.true; - expect(localDeleteStub.called).to.be.false; - expect(inboxFolder.messages).to.contain(message); - - done(); - }); - }); - - it('should fail at delete from imap in offline', function(done) { - account.online = false; - dao.deleteMessage({ - folder: inboxFolder, - message: message - }, function(err) { - expect(err).to.exist; - expect(imapDeleteStub.called).to.be.false; - expect(localDeleteStub.called).to.be.false; - expect(inboxFolder.messages).to.contain(message); - - done(); - }); - }); - }); - - describe('#setFlags', function() { - var imapMark, localListStub, localStoreStub, message; - - beforeEach(function() { - message = { - uid: 1234 - }; - imapMark = sinon.stub(dao, '_imapMark'); - localListStub = sinon.stub(dao, '_localListMessages'); - localStoreStub = sinon.stub(dao, '_localStoreMessages'); - inboxFolder.messages = [message]; - outboxFolder.messages = [message]; - }); - - it('should set flags for imap, disk, memory', function(done) { - imapMark.withArgs({ - folder: inboxFolder, - uid: message.uid, - unread: message.unread, - answered: message.answered - }).yieldsAsync(); - - localListStub.withArgs({ - folder: inboxFolder, - uid: message.uid - }).yieldsAsync(null, [message]); - - localStoreStub.withArgs({ - folder: inboxFolder, - emails: [message] - }).yieldsAsync(); - - dao.setFlags({ - folder: inboxFolder, - message: message - }, function(err) { - expect(err).to.not.exist; - expect(imapMark.calledOnce).to.be.true; - expect(localListStub.calledOnce).to.be.true; - expect(localStoreStub.calledOnce).to.be.true; - - done(); - }); - }); - - it('should set flags for outbox for disk, memory', function(done) { - localListStub.withArgs({ - folder: outboxFolder, - uid: message.uid - }).yieldsAsync(null, [message]); - - localStoreStub.withArgs({ - folder: outboxFolder, - emails: [message] - }).yieldsAsync(); - - dao.setFlags({ - folder: outboxFolder, - message: message - }, function(err) { - expect(err).to.not.exist; - expect(imapMark.called).to.be.false; - expect(localListStub.calledOnce).to.be.true; - expect(localStoreStub.calledOnce).to.be.true; - - done(); - }); - }); - - it('should set flags for disk, memory', function(done) { - localListStub.withArgs({ - folder: inboxFolder, - uid: message.uid - }).yieldsAsync(null, [message]); - - localStoreStub.withArgs({ - folder: inboxFolder, - emails: [message] - }).yieldsAsync(); - - dao.setFlags({ - folder: inboxFolder, - message: message, - localOnly: true - }, function(err) { - expect(err).to.not.exist; - expect(imapMark.called).to.be.false; - expect(localListStub.calledOnce).to.be.true; - expect(localStoreStub.calledOnce).to.be.true; - - done(); - }); - }); - - it('should fail to set flags for imap', function(done) { - imapMark.yieldsAsync({}); - localListStub.yieldsAsync(null, [message]); - localStoreStub.yieldsAsync(); - - dao.setFlags({ - folder: inboxFolder, - message: message - }, function(err) { - expect(err).to.exist; - expect(imapMark.calledOnce).to.be.true; - expect(localListStub.called).to.be.false; - expect(localStoreStub.called).to.be.false; - - done(); - }); - }); - it('should fail to set flags for imap in offline mode', function(done) { - account.online = false; - localListStub.yieldsAsync(null, [message]); - localStoreStub.yieldsAsync(); - - dao.setFlags({ - folder: inboxFolder, - message: message - }, function(err) { - expect(err).to.exist; - expect(imapMark.called).to.be.false; - expect(localListStub.called).to.be.false; - expect(localStoreStub.called).to.be.false; - - done(); - }); - }); - }); - - describe('#getBody', function() { - var localListStub, localStoreStub, imapGetStub, uid; - - beforeEach(function() { - uid = 12345, - localListStub = sinon.stub(dao, '_localListMessages'); - localStoreStub = sinon.stub(dao, '_localStoreMessages'); - imapGetStub = sinon.stub(dao, '_getBodyParts'); - }); - - it('should not do anything if the message already has content', function() { - var message = { - body: 'bender is great!' - }; - - dao.getBody({ - message: message - }); - - // should do nothing - }); - - it('should read an unencrypted body from the device', function(done) { - var message, body; - - body = 'bender is great! bender is great!'; - message = { - uid: uid - }; - - localListStub.withArgs({ - folder: inboxFolder, - uid: uid - }).yieldsAsync(null, [{ - bodyParts: [{ - type: 'text', - content: body - }] - }]); - - dao.getBody({ - message: message, - folder: inboxFolder - }, function(err, msg) { - expect(err).to.not.exist; - - expect(msg).to.equal(message); - expect(msg.body).to.equal(body); - expect(msg.loadingBody).to.be.false; - - expect(localListStub.calledOnce).to.be.true; - - done(); - }); - expect(message.loadingBody).to.be.true; - }); - - it('should read a pgp/mime from the device', function(done) { - var message, ct, pt; - - pt = 'bender is great!'; - ct = '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----'; - message = { - uid: uid, - encrypted: true - }; - - localListStub.withArgs({ - folder: inboxFolder, - uid: uid - }).yieldsAsync(null, [{ - bodyParts: [{ - type: 'text', - content: pt - }, { - type: 'encrypted', - content: ct - }] - }]); - - dao.getBody({ - message: message, - folder: inboxFolder - }, function(err, msg) { - expect(err).to.not.exist; - - expect(msg).to.equal(message); - expect(msg.body).to.equal(ct); - expect(msg.encrypted).to.be.true; - expect(message.loadingBody).to.be.false; - - expect(localListStub.calledOnce).to.be.true; - - done(); - }); - expect(message.loadingBody).to.be.true; - }); - - it('should read a pgp/inline from the device', function(done) { - var message, ct, pt; - - ct = '-----BEGIN PGP MESSAGE-----\nasdasdasd\n-----END PGP MESSAGE-----'; - pt = 'bla bla yadda yadda'; - message = { - uid: uid - }; - - localListStub.yieldsAsync(null, [{ - bodyParts: [{ - type: 'text', - content: pt - }, { - type: 'text', - content: ct - }, { - type: 'text', - content: pt - }] - }]); - - dao.getBody({ - message: message, - folder: inboxFolder - }, function(err, msg) { - expect(err).to.not.exist; - - expect(msg).to.equal(message); - expect(msg.body).to.equal(ct); - expect(msg.bodyParts[0].type).to.equal('encrypted'); - expect(msg.bodyParts[0].content).to.equal(ct); - expect(msg.encrypted).to.be.true; - expect(message.loadingBody).to.be.false; - - expect(localListStub.calledOnce).to.be.true; - - done(); - }); - expect(message.loadingBody).to.be.true; - }); - - it('should stream from imap and set plain text body', function(done) { - var message, body, uid; - - body = 'bender is great! bender is great!'; - uid = 1234; - message = { - uid: uid, - bodyParts: [{ - type: 'text' - }] - }; - - localListStub.withArgs({ - folder: inboxFolder, - uid: uid - }).yieldsAsync(null, [message]); - - localStoreStub.withArgs({ - folder: inboxFolder, - emails: [message] - }).yieldsAsync(); - - imapGetStub.withArgs({ - folder: inboxFolder, - uid: message.uid, - bodyParts: message.bodyParts - }).yieldsAsync(null, [{ - type: 'text', - content: body - }]); - - dao.getBody({ - message: message, - folder: inboxFolder - }, function(err, msg) { - expect(err).to.not.exist; - - expect(msg).to.equal(message); - expect(msg.body).to.equal(body); - expect(msg.loadingBody).to.be.false; - - expect(localListStub.calledOnce).to.be.true; - expect(imapGetStub.calledOnce).to.be.true; - expect(localStoreStub.calledOnce).to.be.true; - - done(); - }); - expect(message.loadingBody).to.be.true; - }); - - it('should stream from imap and set encrypted body', function(done) { - var message, ct, pt; - - pt = 'bender is great'; - ct = '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----'; - message = { - uid: uid, - encrypted: true, - bodyParts: [{ - type: 'text' - }, { - type: 'encrypted' - }] - }; - - localListStub.withArgs({ - folder: inboxFolder, - uid: uid - }).yieldsAsync(null, [message]); - - localStoreStub.withArgs({ - folder: inboxFolder, - emails: [message] - }).yieldsAsync(); - - imapGetStub.withArgs({ - folder: inboxFolder, - uid: message.uid, - bodyParts: message.bodyParts - }).yieldsAsync(null, [{ - type: 'text', - content: pt - }, { - type: 'encrypted', - content: ct - }]); - - - dao.getBody({ - message: message, - folder: inboxFolder - }, function(err, msg) { - expect(err).to.not.exist; - - expect(msg).to.equal(message); - expect(msg.body).to.equal(ct); - expect(msg.encrypted).to.be.true; - expect(msg.loadingBody).to.be.false; - - expect(localListStub.calledOnce).to.be.true; - expect(imapGetStub.calledOnce).to.be.true; - expect(localStoreStub.calledOnce).to.be.true; - - done(); - }); - expect(message.loadingBody).to.be.true; - }); - - it('fail to stream from imap due to error when persisting', function(done) { - var message = { - uid: uid, - bodyParts: [{ - type: 'text' - }] - }; - - localListStub.yieldsAsync(null, [message]); - localStoreStub.yieldsAsync({}); - imapGetStub.yieldsAsync(null, [{ - type: 'text', - content: 'bender is great! bender is great!' - }]); - - dao.getBody({ - message: message, - folder: inboxFolder - }, function(err, msg) { - expect(err).to.exist; - expect(msg).to.not.exist; - expect(localListStub.calledOnce).to.be.true; - expect(imapGetStub.calledOnce).to.be.true; - expect(localStoreStub.calledOnce).to.be.true; - - expect(message.loadingBody).to.be.false; - - done(); - }); - }); - - it('fail to stream from imap due to stream error', function(done) { - var message = { - uid: uid, - bodyParts: [{ - type: 'text' - }] - }; - - localListStub.yieldsAsync(null, [message]); - imapGetStub.yieldsAsync({}); - - dao.getBody({ - message: message, - folder: inboxFolder - }, function(err, msg) { - expect(err).to.exist; - expect(msg).to.not.exist; - expect(localListStub.calledOnce).to.be.true; - expect(imapGetStub.calledOnce).to.be.true; - expect(localStoreStub.called).to.be.false; - - expect(message.loadingBody).to.be.false; - - done(); - }); - }); - }); - - describe('#getAttachment', function() { - var imapGetStub, uid; - - beforeEach(function() { - uid = 123456; - imapGetStub = sinon.stub(dao, '_getBodyParts'); - }); - - it('should fetch an attachment from imap', function(done) { - var attmt = {}; - - imapGetStub.withArgs({ - folder: inboxFolder, - uid: uid, - bodyParts: [attmt] - }).yieldsAsync(null, [{ - content: 'CONTENT!!!' - }]); - - dao.getAttachment({ - folder: inboxFolder, - uid: uid, - attachment: attmt - }, function(err, fetchedAttmt) { - expect(err).to.not.exist; - expect(fetchedAttmt).to.equal(attmt); - expect(attmt.content).to.not.be.empty; - expect(imapGetStub.calledOnce).to.be.true; - - done(); - }); - }); - - it('should error during fetch', function(done) { - var attmt = {}; - - imapGetStub.yieldsAsync({}); - - dao.getAttachment({ - folder: inboxFolder, - uid: uid, - attachment: attmt - }, function(err, fetchedAttmt) { - expect(err).to.exist; - expect(fetchedAttmt).to.not.exist; - expect(imapGetStub.calledOnce).to.be.true; - - done(); - }); - }); - }); - - describe('#decryptBody', function() { - it('should do nothing when the message is not encrypted', function(done) { - var message = { - encrypted: false, - decrypted: true, - body: 'asd' - }; - - dao.decryptBody({ - message: message - }, done); - }); - - it('should do nothing when the message is already decrypted', function(done) { - var message = { - encrypted: true, - decrypted: true, - body: 'asd' - }; - - dao.decryptBody({ - message: message - }, done); - }); - - it('should do nothing when the message has no body', function(done) { - var message = { - encrypted: true, - decrypted: false, - body: '' - }; - - dao.decryptBody({ - message: message - }, done); - }); - - it('should do nothing when the message is decrypting', function(done) { - var message = { - encrypted: true, - decrypted: false, - body: 'asd', - decryptingBody: true - }; - - dao.decryptBody({ - message: message - }, done); - }); - - it('decrypt a pgp/mime message', function(done) { - var message, ct, pt, parsed; - - pt = 'bender is great'; - ct = '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----'; - parsed = 'bender! bender! bender!'; - message = { - from: [{ - address: 'asdasdasd' - }], - body: ct, - encrypted: true, - bodyParts: [{ - type: 'encrypted', - content: ct - }] - }; - - keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey); - pgpStub.decrypt.withArgs(ct, mockKeyPair.publicKey.publicKey).yieldsAsync(null, pt); - parseStub.withArgs({ - bodyParts: [{ - type: 'encrypted', - content: ct, - raw: pt - }] - }).yieldsAsync(null, [{ - type: 'encrypted', - content: [{ - type: 'text', - content: parsed - }] - }]); - - dao.decryptBody({ - message: message - }, function(error, msg) { - expect(error).to.not.exist; - expect(msg).to.equal(message); - expect(message.decrypted).to.be.true; - expect(message.body).to.equal(parsed); - expect(message.decryptingBody).to.be.false; - expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true; - expect(pgpStub.decrypt.calledOnce).to.be.true; - expect(parseStub.calledOnce).to.be.true; - - done(); - }); - - expect(message.decryptingBody).to.be.true; - }); - - it('decrypt a pgp/inline message', function(done) { - var message, ct, pt; - - pt = 'bender is great'; - ct = '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----'; - message = { - from: [{ - address: 'asdasdasd' - }], - body: ct, - encrypted: true, - bodyParts: [{ - type: 'encrypted', - content: ct, - _isPgpInline: true - }] - }; - - keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey); - pgpStub.decrypt.withArgs(ct, mockKeyPair.publicKey.publicKey).yieldsAsync(null, pt); - - dao.decryptBody({ - message: message - }, function(error, msg) { - expect(error).to.not.exist; - - expect(msg).to.equal(message); - expect(message.decrypted).to.be.true; - expect(message.body).to.equal(pt); - expect(message.decryptingBody).to.be.false; - expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true; - expect(pgpStub.decrypt.calledOnce).to.be.true; - expect(parseStub.called).to.be.false; - - done(); - }); - - expect(message.decryptingBody).to.be.true; - }); - - it('should fail during decryption message', function(done) { - var message = { - from: [{ - address: 'asdasdasd' - }], - body: 'asdjafuad', - encrypted: true, - bodyParts: [{ - type: 'encrypted', - content: '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----' - }] - }; - - keychainStub.getReceiverPublicKey.yieldsAsync(null, mockKeyPair.publicKey); - pgpStub.decrypt.yieldsAsync({ - errMsg: 'asd' - }); - - dao.decryptBody({ - message: message - }, function(error, msg) { - expect(error).to.not.exist; - expect(msg.body).to.equal('asd'); - expect(msg).to.exist; - expect(message.decryptingBody).to.be.false; - expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true; - expect(pgpStub.decrypt.calledOnce).to.be.true; - expect(parseStub.called).to.be.false; - - done(); - }); - }); - - it('should fail during key export', function(done) { - var message = { - from: [{ - address: 'asdasdasd' - }], - encrypted: true, - body: 'asdjafuad', - bodyParts: [{ - type: 'encrypted', - content: '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----' - }] - }; - - keychainStub.getReceiverPublicKey.yieldsAsync({}); - - dao.decryptBody({ - message: message - }, function(error, msg) { - expect(error).to.exist; - expect(msg).to.not.exist; - expect(message.decryptingBody).to.be.false; - expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true; - expect(pgpStub.decrypt.called).to.be.false; - expect(parseStub.called).to.be.false; - - done(); - }); - }); - }); - - describe('#sendEncrypted', function() { - var publicKeys = ["PUBLIC KEY"], - dummyMail = { - publicKeysArmored: publicKeys - }; - - it('should send encrypted', function(done) { - pgpMailerStub.send.withArgs({ - encrypt: true, - cleartextMessage: str.message + str.signature, - mail: dummyMail, - smtpclient: undefined, - publicKeysArmored: publicKeys - }).yieldsAsync(); - - dao.sendEncrypted({ - email: dummyMail - }, function(err) { - expect(err).to.not.exist; - - expect(pgpMailerStub.send.calledOnce).to.be.true; - - done(); - }); - }); - - it('should not send when pgpmailer fails', function(done) { - pgpMailerStub.send.yieldsAsync({}); - - dao.sendEncrypted({ - email: dummyMail - }, function(err) { - expect(err).to.exist; - - expect(pgpMailerStub.send.calledOnce).to.be.true; - - done(); - }); - }); - - it('should not send in offline mode', function(done) { - account.online = false; - - dao.sendEncrypted({}, function(err) { - expect(err).to.exist; - expect(pgpMailerStub.send.called).to.be.false; - done(); - }); - }); - - }); - - describe('#sendPlaintext', function() { - var dummyMail = {}; - - it('should send in the plain', function(done) { - pgpMailerStub.send.withArgs({ - smtpclient: undefined, - mail: dummyMail - }).yieldsAsync(); - - dao.sendPlaintext({ - email: dummyMail - }, function(err) { - expect(err).to.not.exist; - expect(pgpMailerStub.send.calledOnce).to.be.true; - done(); - }); - }); - - it('should not send due to error', function(done) { - pgpMailerStub.send.yieldsAsync({}); - - dao.sendPlaintext({ - email: dummyMail - }, function(err) { - expect(err).to.exist; - expect(pgpMailerStub.send.calledOnce).to.be.true; - done(); - }); - }); - - it('should not send in offline mode', function(done) { - account.online = false; - - dao.sendPlaintext({}, function(err) { - expect(err).to.exist; - expect(pgpMailerStub.send.called).to.be.false; - done(); - }); - }); - }); - - describe('#encrypt', function() { - it('should encrypt', function(done) { - pgpBuilderStub.encrypt.yieldsAsync(); - - dao.encrypt({}, function() { - expect(pgpBuilderStub.encrypt.calledOnce).to.be.true; - done(); - }); - }); - }); - }); - - describe('event handlers', function() { - - describe('#onConnect', function() { - var initFoldersStub; - - beforeEach(function() { - initFoldersStub = sinon.stub(dao, '_initFoldersFromImap'); - delete dao._imapClient; - delete dao._pgpMailer; - }); - - it('should connect', function(done) { - inboxFolder.messages = [{ - uid: 123, - modseq: 123 - }]; - imapClientStub.login.yieldsAsync(); - imapClientStub.listenForChanges.yieldsAsync(); - initFoldersStub.yieldsAsync(); - - dao.onConnect({ - imapClient: imapClientStub, - pgpMailer: pgpMailerStub - }, function(err) { - - expect(err).to.not.exist; - expect(imapClientStub.login.calledOnce).to.be.true; - expect(initFoldersStub.calledOnce).to.be.true; - expect(imapClientStub.mailboxCache).to.deep.equal({ - 'INBOX': { - exists: 123, - uidNext: 124, - uidlist: [123], - highestModseq: 123 - } - }); - - done(); - }); - }); - }); - - describe('#onDisconnect', function() { - it('should discard imapClient and pgpMailer', function() { - dao.onDisconnect(); - - expect(dao._account.online).to.be.false; - expect(dao._imapClient).to.not.exist; - expect(dao._pgpMailer).to.not.exist; - }); - }); - - describe('#_onSyncUpdate', function() { - var fetchMessagesStub, deleteMessagesStub, setFlagsStub, msgs; - - beforeEach(function() { - msgs = [{ - uid: 5, - flags: ['\\Answered', '\\Seen'] - }]; - inboxFolder.messages = msgs; - fetchMessagesStub = sinon.stub(dao, 'fetchMessages'); - deleteMessagesStub = sinon.stub(dao, 'deleteMessage'); - setFlagsStub = sinon.stub(dao, 'setFlags'); - }); - - it('should get new message', function(done) { - fetchMessagesStub.withArgs({ - folder: inboxFolder, - firstUid: 1, - lastUid: 3 - }).yieldsAsync(); - - dao.onError = function(err) { - expect(err).to.not.exist; - expect(fetchMessagesStub.calledOnce).to.be.true; - done(); - }; - - dao._onSyncUpdate({ - type: 'new', - path: inboxFolder.path, - list: [1, 3] - }); - }); - - it('should delete message', function(done) { - deleteMessagesStub.withArgs({ - folder: inboxFolder, - message: msgs[0], - localOnly: true - }).yieldsAsync(); - - dao.onError = function(err) { - expect(err).to.not.exist; - expect(deleteMessagesStub.calledOnce).to.be.true; - done(); - }; - - dao._onSyncUpdate({ - type: 'deleted', - path: inboxFolder.path, - list: [5] - }); - }); - - it('should fetch flags', function(done) { - setFlagsStub.withArgs({ - folder: inboxFolder, - message: msgs[0], - localOnly: true - }).yieldsAsync(); - - dao.onError = function(err) { - expect(err).to.not.exist; - expect(setFlagsStub.calledOnce).to.be.true; - done(); - }; - - dao._onSyncUpdate({ - type: 'messages', - path: inboxFolder.path, - list: msgs - }); - }); - }); - }); - - - describe('internal API', function() { - describe('#_initFoldersFromDisk', function() { - beforeEach(function() { - sinon.stub(dao, 'refreshFolder'); - }); - - it('should initialize from disk if offline and not refresh folder', function(done) { - devicestorageStub.listItems.withArgs('folders').yieldsAsync(null, [ - [inboxFolder] - ]); - dao.refreshFolder.withArgs({ - folder: inboxFolder - }).yieldsAsync(); - - dao._initFoldersFromDisk(function(err) { - expect(err).to.not.exist; - expect(devicestorageStub.listItems.calledOnce).to.be.true; - expect(dao.refreshFolder.called).to.be.false; - done(); - }); - }); - - it('should initialize from disk if offline and refresh folder', function(done) { - delete inboxFolder.messages; - devicestorageStub.listItems.withArgs('folders').yieldsAsync(null, [ - [inboxFolder] - ]); - dao.refreshFolder.withArgs({ - folder: inboxFolder - }).yieldsAsync(); - - dao._initFoldersFromDisk(function(err) { - expect(err).to.not.exist; - expect(devicestorageStub.listItems.calledOnce).to.be.true; - expect(dao.refreshFolder.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('#_initFoldersFromImap', function() { - beforeEach(function() { - sinon.stub(dao, 'refreshFolder'); - }); - - it('should initialize from imap if online', function(done) { - account.folders = []; - imapClientStub.listWellKnownFolders.yieldsAsync(null, { - inbox: inboxFolder, - sent: sentFolder, - drafts: draftsFolder, - trash: trashFolder - }); - devicestorageStub.storeList.withArgs(sinon.match(function(arg) { - expect(arg[0][0]).to.deep.equal(inboxFolder); - expect(arg[0][1]).to.deep.equal(sentFolder); - expect(arg[0][2].path).to.deep.equal(outboxFolder.path); - expect(arg[0][2].type).to.deep.equal(outboxFolder.type); - expect(arg[0][3]).to.deep.equal(draftsFolder); - expect(arg[0][4]).to.deep.equal(trashFolder); - return true; - }), 'folders').yieldsAsync(); - - dao.refreshFolder.yieldsAsync(); - - dao._initFoldersFromImap(function(err) { - expect(err).to.not.exist; - expect(imapClientStub.listWellKnownFolders.calledOnce).to.be.true; - expect(devicestorageStub.storeList.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('#_imapMark', function() { - it('should flag a mail', function(done) { - imapClientStub.updateFlags.withArgs({ - path: inboxFolder.path, - folder: inboxFolder, - uid: 1, - unread: false, - answered: false - }).yieldsAsync(); - - dao._imapMark({ - folder: inboxFolder, - uid: 1, - unread: false, - answered: false - }, function(err) { - expect(err).to.not.exist; - expect(imapClientStub.updateFlags.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('#_imapDeleteMessage', function() { - var uid = 1337; - - it('should fail when disconnected', function(done) { - dao._account.online = false; - - dao._imapDeleteMessage({}, function(err) { - expect(err.code).to.equal(42); - done(); - }); - }); - - it('should move to trash', function(done) { - imapClientStub.moveMessage.withArgs({ - path: inboxFolder.path, - uid: uid, - destination: trashFolder.path - }).yieldsAsync(); - - dao._imapDeleteMessage({ - folder: inboxFolder, - uid: uid - }, done); - }); - - it('should purge message', function(done) { - imapClientStub.deleteMessage.withArgs({ - path: trashFolder.path, - uid: uid - }).yieldsAsync(); - - dao._imapDeleteMessage({ - folder: trashFolder, - uid: uid - }, done); - }); - }); - - describe('#_imapListMessages', function() { - var firstUid = 1337, - lastUid = 1339; - - it('should list messages', function(done) { - imapClientStub.listMessages.withArgs({ - folder: inboxFolder, - path: inboxFolder.path, - firstUid: firstUid, - lastUid: lastUid - }).yieldsAsync(null, []); - - dao._imapListMessages({ - folder: inboxFolder, - firstUid: firstUid, - lastUid: lastUid - }, function(err, msgs) { - expect(err).to.not.exist; - expect(msgs).to.exist; - - expect(imapClientStub.listMessages.calledOnce).to.be.true; - - done(); - }); - }); - - it('should fail when listMessages fails', function(done) { - imapClientStub.listMessages.yieldsAsync({}); - - dao._imapListMessages({ - folder: inboxFolder, - firstUid: firstUid, - lastUid: lastUid - }, function(err, msgs) { - expect(err).to.exist; - expect(msgs).to.not.exist; - expect(imapClientStub.listMessages.calledOnce).to.be.true; - - done(); - }); - }); - - it('should fail when disconnected', function(done) { - dao._account.online = false; - - dao._imapListMessages({}, function(err) { - expect(err.code).to.equal(42); - done(); - }); - }); - }); - - describe('#_getBodyParts', function() { - it('should get bodyParts', function(done) { - imapClientStub.getBodyParts.withArgs({ - folder: inboxFolder, - path: inboxFolder.path, - uid: 123, - bodyParts: [] - }).yieldsAsync(null, {}); - parseStub.yieldsAsync(null, []); - - dao._getBodyParts({ - folder: inboxFolder, - uid: 123, - bodyParts: [] - }, function(err, parts) { - expect(err).to.not.exist; - expect(parts).to.exist; - - expect(imapClientStub.getBodyParts.calledOnce).to.be.true; - expect(parseStub.calledOnce).to.be.true; - - done(); - }); - }); - - it('should fail when getBody fails', function(done) { - imapClientStub.getBodyParts.yieldsAsync({}); - - dao._getBodyParts({ - folder: inboxFolder, - uid: 123, - bodyParts: [] - }, function(err, msg) { - expect(err).to.exist; - expect(msg).to.not.exist; - - expect(imapClientStub.getBodyParts.calledOnce).to.be.true; - expect(parseStub.called).to.be.false; - - done(); - }); - }); - - it('should fail when disconnected', function(done) { - dao._account.online = false; - - dao._getBodyParts({}, function(err) { - expect(err.code).to.equal(42); - done(); - }); - }); - }); - - describe('#_localListMessages', function() { - var uid = 123; - - it('should list without uid', function(done) { - devicestorageStub.listItems.withArgs('email_' + inboxFolder.path, 0, null).yieldsAsync(); - - dao._localListMessages({ - folder: inboxFolder - }, done); - }); - - it('should list with uid', function(done) { - devicestorageStub.listItems.withArgs('email_' + inboxFolder.path + '_' + uid, 0, null).yieldsAsync(); - - dao._localListMessages({ - folder: inboxFolder, - uid: uid - }, done); - }); - - }); - - describe('#_localStoreMessages', function() { - it('should store messages', function(done) { - devicestorageStub.storeList.withArgs([{}], 'email_' + inboxFolder.path).yieldsAsync(); - - dao._localStoreMessages({ - folder: inboxFolder, - emails: [{}] - }, done); - }); - }); - - describe('#_localDeleteMessage', function() { - var uid = 1337; - - it('should delete message', function(done) { - devicestorageStub.removeList.withArgs('email_' + inboxFolder.path + '_' + uid).yieldsAsync(); - - dao._localDeleteMessage({ - folder: inboxFolder, - uid: uid - }, done); - }); - - it('should fail when uid is missing', function(done) { - dao._localDeleteMessage({ - folder: inboxFolder - }, function(err) { - expect(err).to.exist; - done(); - }); - }); - - }); - }); - }); -}); \ No newline at end of file diff --git a/test/new-unit/index.html b/test/new-unit/index.html deleted file mode 100644 index 8a0094a..0000000 --- a/test/new-unit/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - JavaScript Unit Tests - - - - -
- - - - - - - - - diff --git a/test/new-unit/keychain-dao-test.js b/test/new-unit/keychain-dao-test.js deleted file mode 100644 index da15115..0000000 --- a/test/new-unit/keychain-dao-test.js +++ /dev/null @@ -1,625 +0,0 @@ -define(function(require) { - 'use strict'; - - var LawnchairDAO = require('js/dao/lawnchair-dao'), - PublicKeyDAO = require('js/dao/publickey-dao'), - KeychainDAO = require('js/dao/keychain-dao'), - expect = chai.expect; - - var testUser = 'test@example.com'; - - describe('Keychain DAO unit tests', function() { - - var keychainDao, lawnchairDaoStub, pubkeyDaoStub; - - beforeEach(function() { - lawnchairDaoStub = sinon.createStubInstance(LawnchairDAO); - pubkeyDaoStub = sinon.createStubInstance(PublicKeyDAO); - keychainDao = new KeychainDAO(lawnchairDaoStub, pubkeyDaoStub); - }); - - afterEach(function() {}); - - describe('verify public key', function() { - it('should verify public key', function(done) { - var uuid = 'asdfasdfasdfasdf'; - pubkeyDaoStub.verify.yields(); - - keychainDao.verifyPublicKey(uuid, function() { - expect(pubkeyDaoStub.verify.calledWith(uuid)).to.be.true; - done(); - }); - }); - }); - - describe('listLocalPublicKeys', function() { - it('should work', function(done) { - lawnchairDaoStub.list.withArgs('publickey', 0, null).yields(); - - keychainDao.listLocalPublicKeys(function() { - expect(lawnchairDaoStub.list.callCount).to.equal(1); - done(); - }); - }); - }); - - describe('removeLocalPublicKey', function() { - it('should work', function(done) { - var id = 'asdf'; - - lawnchairDaoStub.remove.withArgs('publickey_' + id).yields(); - - keychainDao.removeLocalPublicKey(id, function() { - expect(lawnchairDaoStub.remove.callCount).to.equal(1); - done(); - }); - }); - }); - - describe('refreshKeyForUserId', function() { - var getPubKeyStub, - oldKey = { - _id: 123 - }, - newKey = { - _id: 456 - }, - importedKey = { - _id: 789, - imported: true - }; - - beforeEach(function() { - getPubKeyStub = sinon.stub(keychainDao, 'getReceiverPublicKey'); - }); - - afterEach(function() { - keychainDao.getReceiverPublicKey.restore(); - delete keychainDao.requestPermissionForKeyUpdate; - }); - - it('should not find a key', function(done) { - getPubKeyStub.yields(); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.not.exist; - - done(); - }); - }); - - it('should not update the key when up to date', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields(null, oldKey); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.to.equal(oldKey); - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - - - done(); - }); - }); - - it('should update key', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields(); - pubkeyDaoStub.getByUserId.withArgs(testUser).yields(null, newKey); - keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { - expect(opts.userId).to.equal(testUser); - expect(opts.newKey).to.equal(newKey); - cb(true); - }; - lawnchairDaoStub.remove.withArgs('publickey_' + oldKey._id).yields(); - lawnchairDaoStub.persist.withArgs('publickey_' + newKey._id, newKey).yields(); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.equal(newKey); - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - expect(lawnchairDaoStub.remove.calledOnce).to.be.true; - expect(lawnchairDaoStub.persist.calledOnce).to.be.true; - - done(); - }); - }); - - it('should remove key', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields(); - pubkeyDaoStub.getByUserId.withArgs(testUser).yields(); - keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { - expect(opts.userId).to.equal(testUser); - expect(opts.newKey).to.not.exist; - cb(true); - }; - lawnchairDaoStub.remove.withArgs('publickey_' + oldKey._id).yields(); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.not.exist; - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - expect(lawnchairDaoStub.remove.calledOnce).to.be.true; - expect(lawnchairDaoStub.persist.called).to.be.false; - - done(); - }); - }); - - it('should go offline while fetching new key', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields(); - pubkeyDaoStub.getByUserId.withArgs(testUser).yields({ - code: 42 - }); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.to.equal(oldKey); - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - expect(lawnchairDaoStub.remove.called).to.be.false; - expect(lawnchairDaoStub.persist.called).to.be.false; - - done(); - }); - }); - - it('should not remove old key on user rejection', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields(); - pubkeyDaoStub.getByUserId.withArgs(testUser).yields(null, newKey); - keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { - expect(opts.userId).to.equal(testUser); - expect(opts.newKey).to.exist; - cb(false); - }; - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.equal(oldKey); - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - expect(lawnchairDaoStub.remove.called).to.be.false; - expect(lawnchairDaoStub.persist.called).to.be.false; - - done(); - }); - }); - - it('should not remove manually imported key', function(done) { - getPubKeyStub.yields(null, importedKey); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.equal(importedKey); - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.false; - - done(); - }); - }); - - it('should update not the key when offline', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields({ - code: 42 - }); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.to.equal(oldKey); - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.called).to.be.false; - expect(lawnchairDaoStub.remove.called).to.be.false; - expect(lawnchairDaoStub.persist.called).to.be.false; - - done(); - }); - }); - - it('should error while persisting new key', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields(); - pubkeyDaoStub.getByUserId.withArgs(testUser).yields(null, newKey); - keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { - expect(opts.userId).to.equal(testUser); - expect(opts.newKey).to.equal(newKey); - cb(true); - }; - lawnchairDaoStub.remove.withArgs('publickey_' + oldKey._id).yields(); - lawnchairDaoStub.persist.yields({}); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.exist; - expect(key).to.not.exist; - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - expect(lawnchairDaoStub.remove.calledOnce).to.be.true; - expect(lawnchairDaoStub.persist.calledOnce).to.be.true; - - done(); - }); - }); - - it('should error while deleting old key', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields(); - pubkeyDaoStub.getByUserId.withArgs(testUser).yields(); - keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { - expect(opts.userId).to.equal(testUser); - cb(true); - }; - lawnchairDaoStub.remove.yields({}); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.exist; - expect(key).to.not.exist; - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - expect(lawnchairDaoStub.remove.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - expect(lawnchairDaoStub.persist.called).to.be.false; - - done(); - }); - }); - - it('should error while persisting new key', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields(); - pubkeyDaoStub.getByUserId.withArgs(testUser).yields(null, newKey); - keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { - expect(opts.userId).to.equal(testUser); - expect(opts.newKey).to.equal(newKey); - cb(true); - }; - lawnchairDaoStub.remove.withArgs('publickey_' + oldKey._id).yields(); - lawnchairDaoStub.persist.yields({}); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.exist; - expect(key).to.not.exist; - - expect(getPubKeyStub.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - expect(lawnchairDaoStub.remove.calledOnce).to.be.true; - expect(lawnchairDaoStub.persist.calledOnce).to.be.true; - - done(); - }); - }); - - it('should error when get failed', function(done) { - getPubKeyStub.yields(null, oldKey); - pubkeyDaoStub.get.withArgs(oldKey._id).yields({}); - - keychainDao.refreshKeyForUserId(testUser, function(err, key) { - expect(err).to.exist; - expect(key).to.not.exist; - - done(); - }); - }); - }); - - describe('lookup public key', function() { - it('should fail', function(done) { - keychainDao.lookupPublicKey(undefined, function(err, key) { - expect(err).to.exist; - expect(key).to.not.exist; - done(); - }); - }); - - it('should fail', function(done) { - lawnchairDaoStub.read.yields(42); - - keychainDao.lookupPublicKey('12345', function(err, key) { - expect(err).to.exist; - expect(key).to.not.exist; - expect(lawnchairDaoStub.read.calledOnce).to.be.true; - done(); - }); - }); - - it('should work from local storage', function(done) { - lawnchairDaoStub.read.yields(null, { - _id: '12345', - publicKey: 'asdf' - }); - - keychainDao.lookupPublicKey('12345', function(err, key) { - expect(err).to.not.exist; - expect(key).to.exist; - expect(lawnchairDaoStub.read.calledOnce).to.be.true; - done(); - }); - }); - - it('should work from cloud', function(done) { - lawnchairDaoStub.read.yields(); - pubkeyDaoStub.get.yields(null, { - _id: '12345', - publicKey: 'asdf' - }); - lawnchairDaoStub.persist.yields(); - - keychainDao.lookupPublicKey('12345', function(err, key) { - expect(err).to.not.exist; - expect(key).to.exist; - expect(key._id).to.equal('12345'); - expect(lawnchairDaoStub.read.calledOnce).to.be.true; - expect(pubkeyDaoStub.get.calledOnce).to.be.true; - expect(lawnchairDaoStub.persist.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('get public keys by id', function() { - it('should fail', function(done) { - keychainDao.getPublicKeys([], function(err, keys) { - expect(err).to.not.exist; - expect(keys.length).to.equal(0); - done(); - }); - }); - - it('should fail', function(done) { - lawnchairDaoStub.read.yields(42); - - var ids = [{ - _id: '12345' - }]; - keychainDao.getPublicKeys(ids, function(err, keys) { - expect(err).to.exist; - expect(keys).to.not.exist; - expect(lawnchairDaoStub.read.calledOnce).to.be.true; - done(); - }); - }); - - it('should work from local storage', function(done) { - lawnchairDaoStub.read.yields(null, { - _id: '12345', - publicKey: 'asdf' - }); - - var ids = [{ - _id: '12345' - }]; - keychainDao.getPublicKeys(ids, function(err, keys) { - expect(err).to.not.exist; - expect(keys.length).to.equal(1); - expect(keys[0]._id).to.equal('12345'); - expect(lawnchairDaoStub.read.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('get receiver public key', function() { - it('should fail due to error in lawnchair list', function(done) { - lawnchairDaoStub.list.yields(42); - - keychainDao.getReceiverPublicKey(testUser, function(err, key) { - expect(err).to.exist; - expect(key).to.not.exist; - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - done(); - }); - }); - - it('should work from lawnchair list', function(done) { - lawnchairDaoStub.list.yields(null, [{ - _id: '12345', - userId: testUser, - publicKey: 'asdf' - }]); - - keychainDao.getReceiverPublicKey(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.exist; - expect(key._id).to.equal('12345'); - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - done(); - }); - }); - - it('should work for keys with secondary userIds', function(done) { - lawnchairDaoStub.list.yields(null, [{ - _id: '12345', - userId: 'not testUser', - userIds: [{ - emailAddress: testUser - }], - publicKey: 'asdf' - }]); - - keychainDao.getReceiverPublicKey(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.exist; - expect(key._id).to.equal('12345'); - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - done(); - }); - }); - - it('should fail due to error in pubkey dao', function(done) { - lawnchairDaoStub.list.yields(null, []); - pubkeyDaoStub.getByUserId.yields({}); - - keychainDao.getReceiverPublicKey(testUser, function(err, key) { - expect(err).to.exist; - expect(key).to.not.exist; - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - done(); - }); - }); - - it('should work from pubkey dao with empty result', function(done) { - lawnchairDaoStub.list.yields(null, []); - pubkeyDaoStub.getByUserId.yields(); - - keychainDao.getReceiverPublicKey(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.not.exist; - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - done(); - }); - }); - - it('should work from pubkey dao', function(done) { - lawnchairDaoStub.list.yields(null, []); - pubkeyDaoStub.getByUserId.yields(null, { - _id: '12345', - publicKey: 'asdf' - }); - lawnchairDaoStub.persist.yields(); - - keychainDao.getReceiverPublicKey(testUser, function(err, key) { - expect(err).to.not.exist; - expect(key).to.exist; - expect(key._id).to.equal('12345'); - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - expect(lawnchairDaoStub.persist.calledOnce).to.be.true; - done(); - }); - }); - }); - - describe('get user key pair', function() { - it('should work if local keys are already present', function(done) { - lawnchairDaoStub.list.yields(null, [{ - _id: '12345', - userId: testUser, - publicKey: 'asdf' - }]); - lawnchairDaoStub.read.yields(null, { - _id: '12345', - publicKey: 'asdf', - encryptedKey: 'qwer' - }); - - keychainDao.getUserKeyPair(testUser, function(err, keys) { - expect(err).to.not.exist; - expect(keys).to.exist; - expect(keys.publicKey).to.exist; - expect(keys.privateKey).to.exist; - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - expect(lawnchairDaoStub.read.calledTwice).to.be.true; - done(); - }); - }); - - it('should work if local keys are not already present', function(done) { - lawnchairDaoStub.list.yields(); - pubkeyDaoStub.getByUserId.yields(); - - keychainDao.getUserKeyPair(testUser, function(err, keys) { - expect(err).to.not.exist; - expect(keys).to.not.exist; - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; - done(); - }); - }); - - it('should work if local keys are not already present', function(done) { - lawnchairDaoStub.list.yields(); - pubkeyDaoStub.getByUserId.yields(null, { - _id: '12345', - publicKey: 'asdf' - }); - lawnchairDaoStub.read.yields(null, { - _id: '12345', - publicKey: 'asdf', - encryptedKey: 'qwer' - }); - - keychainDao.getUserKeyPair(testUser, function(err, keys) { - expect(err).to.not.exist; - expect(keys).to.exist; - expect(keys.publicKey).to.exist; - expect(keys.privateKey).to.exist; - expect(lawnchairDaoStub.list.calledOnce).to.be.true; - expect(lawnchairDaoStub.read.calledTwice).to.be.true; - done(); - }); - }); - }); - - describe('put user keypair', function() { - it('should fail', function(done) { - var keypair = { - publicKey: { - _id: '12345', - userId: testUser, - publicKey: 'asdf' - }, - privateKey: { - _id: '12345', - encryptedKey: 'qwer' - } - }; - - keychainDao.putUserKeyPair(keypair, function(err) { - expect(err).to.exist; - done(); - }); - }); - - it('should work', function(done) { - var keypair = { - publicKey: { - _id: '12345', - userId: testUser, - publicKey: 'asdf' - }, - privateKey: { - _id: '12345', - userId: testUser, - encryptedKey: 'qwer' - } - }; - - lawnchairDaoStub.persist.yields(); - pubkeyDaoStub.put.yields(); - - keychainDao.putUserKeyPair(keypair, function(err) { - expect(err).to.not.exist; - expect(lawnchairDaoStub.persist.calledTwice).to.be.true; - expect(pubkeyDaoStub.put.calledOnce).to.be.true; - done(); - }); - }); - }); - - }); - -}); \ No newline at end of file diff --git a/test/new-unit/main.js b/test/new-unit/main.js deleted file mode 100644 index f151929..0000000 --- a/test/new-unit/main.js +++ /dev/null @@ -1,62 +0,0 @@ -'use strict'; - -require(['../../src/require-config'], function() { - require.config({ - baseUrl: '../../src/lib', - paths: { - angularMocks: '../../test/lib/angular-mocks' - }, - shim: { - angularMocks: { - exports: 'angular.mock', - deps: ['angular'] - } - } - }); - - - // Start the main app logic. - require(['js/app-config'], function(app) { - app.config.workerPath = '../../src/js'; - - startTests(); - }); -}); - -function startTests() { - mocha.setup('bdd'); - - require( - [ - 'test/new-unit/oauth-test', - 'test/new-unit/auth-test', - 'test/new-unit/email-dao-test', - 'test/new-unit/app-controller-test', - 'test/new-unit/pgp-test', - 'test/new-unit/rest-dao-test', - 'test/new-unit/publickey-dao-test', - 'test/new-unit/lawnchair-dao-test', - 'test/new-unit/keychain-dao-test', - 'test/new-unit/devicestorage-dao-test', - 'test/new-unit/dialog-ctrl-test', - 'test/new-unit/add-account-ctrl-test', - 'test/new-unit/account-ctrl-test', - 'test/new-unit/set-passphrase-ctrl-test', - 'test/new-unit/contacts-ctrl-test', - 'test/new-unit/login-existing-ctrl-test', - 'test/new-unit/login-initial-ctrl-test', - 'test/new-unit/login-new-device-ctrl-test', - 'test/new-unit/login-ctrl-test', - 'test/new-unit/read-ctrl-test', - 'test/new-unit/navigation-ctrl-test', - 'test/new-unit/mail-list-ctrl-test', - 'test/new-unit/write-ctrl-test', - 'test/new-unit/outbox-bo-test', - 'test/new-unit/invitation-dao-test', - 'test/new-unit/update-handler-test' - ], function() { - //Tests loaded, run tests - mocha.run(); - } - ); -} \ No newline at end of file diff --git a/test/new-unit/account-ctrl-test.js b/test/unit/account-ctrl-test.js similarity index 94% rename from test/new-unit/account-ctrl-test.js rename to test/unit/account-ctrl-test.js index f9b74f0..f5c58e0 100644 --- a/test/new-unit/account-ctrl-test.js +++ b/test/unit/account-ctrl-test.js @@ -14,18 +14,18 @@ define(function(require) { var scope, accountCtrl, dummyFingerprint, expectedFingerprint, dummyKeyId, expectedKeyId, - emailAddress, keySize, cryptoMock, keychainMock; + emailAddress, keySize, pgpMock, keychainMock; beforeEach(function() { - appController._crypto = cryptoMock = sinon.createStubInstance(PGP); + appController._pgp = pgpMock = sinon.createStubInstance(PGP); appController._keychain = keychainMock = sinon.createStubInstance(KeychainDAO); dummyFingerprint = '3A2D39B4E1404190B8B949DE7D7E99036E712926'; expectedFingerprint = '3A2D 39B4 E140 4190 B8B9 49DE 7D7E 9903 6E71 2926'; dummyKeyId = '9FEB47936E712926'; expectedKeyId = '6E712926'; - cryptoMock.getFingerprint.returns(dummyFingerprint); - cryptoMock.getKeyId.returns(dummyKeyId); + pgpMock.getFingerprint.returns(dummyFingerprint); + pgpMock.getKeyId.returns(dummyKeyId); emailAddress = 'fred@foo.com'; keySize = 1234; appController._emailDao = { @@ -34,7 +34,7 @@ define(function(require) { asymKeySize: keySize } }; - cryptoMock.getKeyParams.returns({ + pgpMock.getKeyParams.returns({ _id: dummyKeyId, fingerprint: dummyFingerprint, userId: emailAddress, diff --git a/test/new-unit/add-account-ctrl-test.js b/test/unit/add-account-ctrl-test.js similarity index 100% rename from test/new-unit/add-account-ctrl-test.js rename to test/unit/add-account-ctrl-test.js diff --git a/test/unit/aes-test.js b/test/unit/aes-test.js deleted file mode 100644 index 130546f..0000000 --- a/test/unit/aes-test.js +++ /dev/null @@ -1,24 +0,0 @@ -define(['cryptoLib/aes-cbc', 'cryptoLib/util', 'test/test-data'], function(aes, util, testData) { - 'use strict'; - - module("AES Crypto"); - - var aesTest = { - keySize: 128, - testMessage: testData.generateBigString(1000) - }; - - test("CBC mode", 4, function() { - var plaintext = aesTest.testMessage; - var key = util.random(aesTest.keySize); - var iv = util.random(aesTest.keySize); - ok(key, 'Key: ' + key); - equal(util.base642Str(key).length * 8, aesTest.keySize, 'Keysize ' + aesTest.keySize); - - var ciphertext = aes.encrypt(plaintext, key, iv); - ok(ciphertext, 'Ciphertext lenght: ' + ciphertext.length); - - var decrypted = aes.decrypt(ciphertext, key, iv); - equal(decrypted, plaintext, 'Decryption correct' + decrypted); - }); -}); \ No newline at end of file diff --git a/test/new-unit/app-controller-test.js b/test/unit/app-controller-test.js similarity index 99% rename from test/new-unit/app-controller-test.js rename to test/unit/app-controller-test.js index d2ed543..b76caf4 100644 --- a/test/new-unit/app-controller-test.js +++ b/test/unit/app-controller-test.js @@ -37,7 +37,7 @@ define(function(require) { expect(controller._userStorage).to.exist; expect(controller._invitationDao).to.exist; expect(controller._keychain).to.exist; - expect(controller._crypto).to.exist; + expect(controller._pgp).to.exist; expect(controller._pgpbuilder).to.exist; expect(controller._emailDao).to.exist; expect(controller._outboxBo).to.exist; diff --git a/test/new-unit/auth-test.js b/test/unit/auth-test.js similarity index 100% rename from test/new-unit/auth-test.js rename to test/unit/auth-test.js diff --git a/test/new-unit/contacts-ctrl-test.js b/test/unit/contacts-ctrl-test.js similarity index 93% rename from test/new-unit/contacts-ctrl-test.js rename to test/unit/contacts-ctrl-test.js index 2e52d51..15085ef 100644 --- a/test/new-unit/contacts-ctrl-test.js +++ b/test/unit/contacts-ctrl-test.js @@ -12,11 +12,11 @@ define(function(require) { describe('Contacts Controller unit test', function() { var scope, contactsCtrl, origKeychain, keychainMock, - origCrypto, cryptoMock; + origPgp, pgpMock; beforeEach(function() { - origCrypto = appController._crypto; - appController._crypto = cryptoMock = sinon.createStubInstance(PGP); + origPgp = appController._pgp; + appController._pgp = pgpMock = sinon.createStubInstance(PGP); origKeychain = appController._keychain; appController._keychain = keychainMock = sinon.createStubInstance(KeychainDAO); @@ -33,7 +33,7 @@ define(function(require) { afterEach(function() { // restore the module - appController._crypto = origCrypto; + appController._pgp = origPgp; appController._keychain = origKeychain; }); @@ -60,7 +60,7 @@ define(function(require) { keychainMock.listLocalPublicKeys.yields(null, [{ _id: '12345' }]); - cryptoMock.getKeyParams.returns({ + pgpMock.getKeyParams.returns({ fingerprint: 'asdf' }); @@ -92,7 +92,7 @@ define(function(require) { it('should work', function(done) { var keyArmored = '-----BEGIN PGP PUBLIC KEY BLOCK-----'; - cryptoMock.getKeyParams.returns({ + pgpMock.getKeyParams.returns({ _id: '12345', userId: 'max@example.com', userIds: [] @@ -127,7 +127,7 @@ define(function(require) { it('should fail due to error in pgp.getKeyParams', function(done) { var keyArmored = '-----BEGIN PGP PUBLIC KEY BLOCK-----'; - cryptoMock.getKeyParams.throws(new Error('WAT')); + pgpMock.getKeyParams.throws(new Error('WAT')); scope.onError = function(err) { expect(err).to.exist; @@ -140,7 +140,7 @@ define(function(require) { it('should fail due to error in keychain.saveLocalPublicKey', function(done) { var keyArmored = '-----BEGIN PGP PUBLIC KEY BLOCK-----'; - cryptoMock.getKeyParams.returns({ + pgpMock.getKeyParams.returns({ _id: '12345', userId: 'max@example.com' }); diff --git a/test/unit/crypto-test.js b/test/unit/crypto-test.js index 05e4ea4..5cbe272 100644 --- a/test/unit/crypto-test.js +++ b/test/unit/crypto-test.js @@ -1,121 +1,58 @@ -define(['js/crypto/crypto', 'cryptoLib/util', 'test/test-data'], function(Crypto, util, testData) { - 'use strict'; +define(function(require) { + 'use strict'; - module("Crypto Api"); + var Crypto = require('js/crypto/crypto'), + util = require('js/crypto/util'), + config = require('js/app-config').config, + expect = chai.expect; - var cryptoTest = { - user: 'crypto_test@example.com', - password: 'Password', - keySize: 128, - ivSize: 128, - rsaKeySize: 1024, - salt: util.random(128) - }; + describe('Crypto unit tests', function() { + this.timeout(20000); - var crypto; + var crypto, + password = 'password', + keySize = config.symKeySize, + ivSize = config.symIvSize; - asyncTest("Init without keypair", 4, function() { - crypto = new Crypto(); - // init dependencies - ok(crypto, 'Crypto'); + beforeEach(function() { + crypto = new Crypto(); + }); - // test without passing keys - crypto.init({ - emailAddress: cryptoTest.user, - password: cryptoTest.password, - salt: cryptoTest.salt, - keySize: cryptoTest.keySize, - rsaKeySize: cryptoTest.rsaKeySize - }, function(err, generatedKeypair) { - ok(!err && generatedKeypair, 'Init crypto without keypair input'); - var pk = generatedKeypair.publicKey; - ok(pk._id && pk.userId, 'Key ID: ' + pk._id); - ok(pk.publicKey.indexOf('-----BEGIN PUBLIC KEY-----') === 0, pk.publicKey); - cryptoTest.generatedKeypair = generatedKeypair; + afterEach(function() {}); - start(); - }); - }); + describe('AES encrypt/decrypt', function() { + it('should work', function(done) { + var plaintext = 'Hello, World!'; + var key = util.random(keySize); + var iv = util.random(ivSize); - asyncTest("Init with keypair", 1, function() { - // test with passing keypair - crypto.init({ - emailAddress: cryptoTest.user, - password: cryptoTest.password, - salt: cryptoTest.salt, - keySize: cryptoTest.keySize, - rsaKeySize: cryptoTest.rsaKeySize, - storedKeypair: cryptoTest.generatedKeypair - }, function(err, generatedKeypair) { - ok(!err && !generatedKeypair, 'Init crypto with keypair input'); + crypto.encrypt(plaintext, key, iv, function(err, ciphertext) { + expect(err).to.not.exist; + expect(ciphertext).to.exist; - start(); - }); - }); + crypto.decrypt(ciphertext, key, iv, function(err, decrypted) { + expect(err).to.not.exist; + expect(decrypted).to.equal(plaintext); - asyncTest("PBKDF2 (Async/Worker)", 2, function() { - crypto.deriveKey(cryptoTest.password, cryptoTest.salt, cryptoTest.keySize, function(err, key) { - ok(!err); - equal(util.base642Str(key).length * 8, cryptoTest.keySize, 'Keysize ' + cryptoTest.keySize); + done(); + }); + }); + }); + }); - start(); - }); - }); + describe("PBKDF2 (Async/Worker)", function() { + it('should work', function(done) { + var salt = util.random(keySize); - asyncTest("AES/HMAC encrypt batch (Async/Worker)", 2, function() { - // generate test data - cryptoTest.symlist = testData.getEmailCollection(10); + crypto.deriveKey(password, salt, keySize, function(err, key) { + expect(err).to.not.exist; + expect(util.base642Str(key).length * 8).to.equal(keySize); - crypto.symEncryptList(cryptoTest.symlist, function(err, result) { - ok(!err && result.key && result.list && result.list[0].hmac, 'Encrypt list for user'); - equal(result.list.length, cryptoTest.symlist.length, 'Length of list'); - cryptoTest.symEncryptedList = result.list; - cryptoTest.symKey = result.key; + done(); + }); + }); - start(); - }); - }); - - asyncTest("AES/HMAC decrypt batch (Async/Worker)", 3, function() { - var keys = []; - for (var i = 0; i < cryptoTest.symEncryptedList.length; i++) { - keys.push(cryptoTest.symKey); - } - crypto.symDecryptList(cryptoTest.symEncryptedList, keys, function(err, decryptedList) { - ok(!err && decryptedList, 'Decrypt list'); - equal(decryptedList.length, cryptoTest.symlist.length, 'Length of list'); - deepEqual(decryptedList, cryptoTest.symlist, 'Decrypted list is correct'); - - start(); - }); - }); - - asyncTest("AES/RSA encrypt batch for User (Async/Worker)", 2, function() { - // generate test data - cryptoTest.list = testData.getEmailCollection(10); - - var receiverPubkeys = [cryptoTest.generatedKeypair.publicKey]; - - crypto.encryptListForUser(cryptoTest.list, receiverPubkeys, function(err, encryptedList) { - ok(!err && encryptedList, 'Encrypt list for user'); - equal(encryptedList.length, cryptoTest.list.length, 'Length of list'); - cryptoTest.encryptedList = encryptedList; - - start(); - }); - }); - - asyncTest("AES/RSA decrypt batch for User (Async/Worker)", 3, function() { - - var senderPubkeys = [cryptoTest.generatedKeypair.publicKey]; - - crypto.decryptListForUser(cryptoTest.encryptedList, senderPubkeys, function(err, decryptedList) { - ok(!err && decryptedList, 'Decrypt list'); - equal(decryptedList.length, cryptoTest.list.length, 'Length of list'); - deepEqual(decryptedList, cryptoTest.list, 'Decrypted list is correct'); - - start(); - }); - }); + }); + }); }); \ No newline at end of file diff --git a/test/unit/devicestorage-dao-test.js b/test/unit/devicestorage-dao-test.js index 627918f..f593e39 100644 --- a/test/unit/devicestorage-dao-test.js +++ b/test/unit/devicestorage-dao-test.js @@ -1,106 +1,105 @@ -define(['underscore', 'cryptoLib/util', 'js/crypto/crypto', 'js/dao/devicestorage-dao', 'test/test-data', 'js/dao/lawnchair-dao'], function(_, util, Crypto, DeviceStorageDAO, testData, LawnchairDAO) { +define(function(require) { 'use strict'; - module("DeviceStorage"); + var LawnchairDAO = require('js/dao/lawnchair-dao'), + DeviceStorageDAO = require('js/dao/devicestorage-dao'), + expect = chai.expect; - var devicestorageTest = { - user: 'devicestorage_test@example.com', - password: 'Password', - keySize: 128, - ivSize: 128, - rsaKeySize: 1024 - }; + var testUser = 'test@example.com'; - var crypto, storage; + describe('Device Storage DAO unit tests', function() { - asyncTest("Init", 3, function() { - // init dependencies - storage = new DeviceStorageDAO(new LawnchairDAO()); - storage.init(devicestorageTest.user, function() { - ok(storage, 'DeviceStorageDAO'); + var storageDao, lawnchairDaoStub; - // generate test data - devicestorageTest.list = testData.getEmailCollection(100); + beforeEach(function() { + lawnchairDaoStub = sinon.createStubInstance(LawnchairDAO); + storageDao = new DeviceStorageDAO(lawnchairDaoStub); + }); - // init crypto - crypto = new Crypto(); - crypto.init({ - emailAddress: devicestorageTest.user, - password: devicestorageTest.password, - salt: util.random(devicestorageTest.keySize), - keySize: devicestorageTest.keySize, - rsaKeySize: devicestorageTest.rsaKeySize - }, function(err, generatedKeypair) { - ok(!err && generatedKeypair, 'Init crypto'); - devicestorageTest.generatedKeypair = generatedKeypair; + afterEach(function() {}); - // clear db before tests - storage.clear(function(err) { - ok(!err, 'DB cleared. Error status: ' + err); + describe('init', function() { + it('should work', function(done) { + lawnchairDaoStub.init.yields(); - start(); + storageDao.init(testUser, function(err) { + expect(err).to.not.exist; + expect(lawnchairDaoStub.init.calledOnce).to.be.true; + done(); }); - }); }); - }); - asyncTest("Encrypt list for user", 2, function() { - var receiverPubkeys = [devicestorageTest.generatedKeypair.publicKey]; + describe('store list', function() { + it('should fail', function(done) { + var list = [{}]; - crypto.encryptListForUser(devicestorageTest.list, receiverPubkeys, function(err, encryptedList) { - ok(!err); - equal(encryptedList.length, devicestorageTest.list.length, 'Encrypt list'); - - encryptedList.forEach(function(i) { - i.sentDate = _.findWhere(devicestorageTest.list, { - id: i.id - }).sentDate; + storageDao.storeList(list, '', function(err) { + expect(err).to.exist; + done(); + }); }); - devicestorageTest.encryptedList = encryptedList; - start(); - }); - }); + it('should work with empty list', function(done) { + var list = []; - asyncTest("Store encrypted list", 1, function() { - storage.storeList(devicestorageTest.encryptedList, 'email_inbox', function() { - ok(true, 'Store encrypted list'); + storageDao.storeList(list, 'email', function(err) { + expect(err).to.not.exist; + done(); + }); + }); - start(); - }); - }); + it('should work', function(done) { + lawnchairDaoStub.batch.yields(); - asyncTest("List items", 4, function() { - var senderPubkeys = [devicestorageTest.generatedKeypair.publicKey]; + var list = [{ + foo: 'bar' + }]; - var offset = 2, - num = 6; - - // list encrypted items from storage - storage.listItems('email_inbox', offset, num, function(err, encryptedList) { - ok(!err); - - // decrypt list - crypto.decryptListForUser(encryptedList, senderPubkeys, function(err, decryptedList) { - ok(!err); - equal(decryptedList.length, num, 'Found ' + decryptedList.length + ' items in store (and decrypted)'); - - var origSet = devicestorageTest.list.splice(92, num); - deepEqual(decryptedList, origSet, 'Messages decrypted correctly'); - - start(); + storageDao.storeList(list, 'email', function(err) { + expect(err).to.not.exist; + expect(lawnchairDaoStub.batch.calledOnce).to.be.true; + done(); + }); }); }); - }); - asyncTest("Delete List items", 1, function() { - // list encrypted items from storage - storage.removeList('email_inbox', function(err) { - ok(!err); + describe('remove list', function() { + it('should work', function(done) { + lawnchairDaoStub.removeList.yields(); - start(); + storageDao.removeList('email', function(err) { + expect(err).to.not.exist; + expect(lawnchairDaoStub.removeList.calledOnce).to.be.true; + done(); + }); + }); }); + + describe('list items', function() { + it('should work', function(done) { + lawnchairDaoStub.list.yields(); + + storageDao.listItems('email', 0, null, function(err) { + expect(err).to.not.exist; + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('clear', function() { + it('should work', function(done) { + lawnchairDaoStub.clear.yields(); + + storageDao.clear(function(err) { + expect(err).to.not.exist; + expect(lawnchairDaoStub.clear.calledOnce).to.be.true; + done(); + }); + }); + }); + }); }); \ No newline at end of file diff --git a/test/new-unit/dialog-ctrl-test.js b/test/unit/dialog-ctrl-test.js similarity index 100% rename from test/new-unit/dialog-ctrl-test.js rename to test/unit/dialog-ctrl-test.js diff --git a/test/unit/email-dao-test.js b/test/unit/email-dao-test.js index a216657..5215772 100644 --- a/test/unit/email-dao-test.js +++ b/test/unit/email-dao-test.js @@ -1,105 +1,1909 @@ -define(['js/dao/email-dao', 'js/dao/keychain-dao', 'js/dao/lawnchair-dao', - 'js/crypto/crypto', 'js/dao/devicestorage-dao', 'test/test-data', 'js/app-config' -], function(EmailDAO, KeychainDAO, jsonDao, crypto, storage, testData, app) { - 'use strict'; +define(function(require) { + 'use strict'; - module("Email DAO"); + var EmailDAO = require('js/dao/email-dao'), + KeychainDAO = require('js/dao/keychain-dao'), + ImapClient = require('imap-client'), + PgpMailer = require('pgpmailer'), + PgpBuilder = require('pgpbuilder'), + PGP = require('js/crypto/pgp'), + DeviceStorageDAO = require('js/dao/devicestorage-dao'), + mailreader = require('mailreader'), + appcfg = require('js/app-config'), + str = appcfg.string, + cfg = appcfg.config, + expect = chai.expect; - var emaildaoTest = { - user: 'test@atlasdev.onmicrosoft.com', - password: 'Xoza76645', - keySize: 128, - ivSize: 128, - rsaKeySize: 1024 - }; - asyncTest("Init", 3, function() { - // init dependencies - jsonDao.init(emaildaoTest.user); - // cloud storage stub - emaildaoTest.cloudstorageStub = { - putPublicKey: function(pk, callback) { - callback(); - }, - putPrivateKey: function(prk, callback) { - callback(); - }, - getPublicKeyByUserId: function(userId, callback) { - callback(); - } - }; - emaildaoTest.keychain = new KeychainDAO(emaildaoTest.cloudstorageStub); - emaildaoTest.emailDao = new EmailDAO(emaildaoTest.cloudstorageStub, emaildaoTest.keychain); + describe('Email DAO unit tests', function() { + // show the stack trace when an error occurred + chai.Assertion.includeStack = true; - // generate test data - emaildaoTest.list = testData.getEmailCollection(100); + // SUT + var dao; - var account = new app.model.Account({ - emailAddress: emaildaoTest.user, - symKeySize: emaildaoTest.keySize, - symIvSize: emaildaoTest.ivSize, - asymKeySize: emaildaoTest.rsaKeySize - }); + // mocks + var keychainStub, imapClientStub, pgpMailerStub, pgpBuilderStub, pgpStub, devicestorageStub, parseStub; - // clear db before tests - jsonDao.clear(function(err) { - ok(!err, 'DB cleared. Error status: ' + err); + // config + var emailAddress, passphrase, asymKeySize, account; - emaildaoTest.emailDao.init(account, emaildaoTest.password, function(err) { - ok(!err); - equal(emaildaoTest.emailDao.account.get('emailAddress'), emaildaoTest.user, 'Email DAO Account'); + // test data + var folders, inboxFolder, sentFolder, draftsFolder, outboxFolder, trashFolder, mockKeyPair; - start(); - }); - }); - }); + beforeEach(function() { + // + // test data + // + emailAddress = 'asdf@asdf.com'; + passphrase = 'asdf'; + asymKeySize = 2048; - asyncTest("Persist test emails (stubbed sync from cloud)", 4, function() { - emaildaoTest.keychain.getUserKeyPair(emaildaoTest.user, function(err, keypair) { - ok(!err && keypair, 'Fetch keypair from keychain'); + inboxFolder = { + type: 'Inbox', + path: 'INBOX', + messages: [] + }; - var receiverPubkeys = [keypair.publicKey]; + sentFolder = { + type: 'Sent', + path: 'SENT', + messages: [] + }; - crypto.encryptListForUser(emaildaoTest.list, receiverPubkeys, function(err, encryptedList) { - ok(!err); - equal(encryptedList.length, emaildaoTest.list.length, 'Encrypt list'); + draftsFolder = { + type: 'Drafts', + path: 'DRAFTS', + messages: [] + }; - // add sent date to encrypted items - for (var i = 0; i < encryptedList.length; i++) { - encryptedList[i].sentDate = emaildaoTest.list[i].sentDate; - } + outboxFolder = { + type: 'Outbox', + path: 'OUTBOX', + messages: [] + }; - // set encrypted test list as return value for cloud storage stub - emaildaoTest.cloudstorageStub.listEncryptedItems = function(type, emailAddress, folderName, callback) { - callback(null, encryptedList); - }; + trashFolder = { + type: 'Trash', + path: 'TRASH', + messages: [] + }; - emaildaoTest.emailDao.syncFromCloud('inbox', function() { - ok(true, 'Stored encrypted list'); + folders = [inboxFolder, outboxFolder, trashFolder]; - start(); - }); - }); - }); - }); + account = { + emailAddress: emailAddress, + asymKeySize: asymKeySize, + folders: folders, + online: true + }; - asyncTest("List Email models", 2, function() { - emaildaoTest.emailDao.listItems('inbox', 0, emaildaoTest.list.length, function(err, gotten) { - ok(!err); + mockKeyPair = { + publicKey: { + _id: 1234, + userId: emailAddress, + publicKey: 'publicpublicpublicpublic' + }, + privateKey: { + _id: 1234, + userId: emailAddress, + encryptedKey: 'privateprivateprivateprivate' + } + }; - var reference = emaildaoTest.list; + // + // setup the mocks + // + keychainStub = sinon.createStubInstance(KeychainDAO); + imapClientStub = sinon.createStubInstance(ImapClient); + pgpMailerStub = sinon.createStubInstance(PgpMailer); + pgpBuilderStub = sinon.createStubInstance(PgpBuilder); + pgpStub = sinon.createStubInstance(PGP); + parseStub = sinon.stub(mailreader, 'parse'); + devicestorageStub = sinon.createStubInstance(DeviceStorageDAO); - deepEqual(gotten, reference, 'Compare collection'); + // + // setup the SUT + // + dao = new EmailDAO(keychainStub, pgpStub, devicestorageStub, pgpBuilderStub, mailreader); + dao._account = account; + dao._pgpMailer = pgpMailerStub; + dao._imapClient = imapClientStub; - start(); - }); - }); + // + // check configuration + // + expect(dao._keychain).to.equal(keychainStub); + expect(dao._pgp).to.equal(pgpStub); + expect(dao._devicestorage).to.equal(devicestorageStub); + expect(dao._mailreader).to.equal(mailreader); + expect(dao._pgpbuilder).to.equal(pgpBuilderStub); + }); - asyncTest("Get item", 1, function() { - var item = emaildaoTest.list[0]; - var mail = emaildaoTest.emailDao.getItem('inbox', item.id); - deepEqual(mail, item, 'Item correct'); - start(); - }); + afterEach(function() { + mailreader.parse.restore(); + }); + describe('public API', function() { + describe('#init', function() { + var initFoldersStub; + + beforeEach(function() { + delete dao._account; + initFoldersStub = sinon.stub(dao, '_initFoldersFromDisk'); + }); + + it('should initialize folders and return keypair', function(done) { + keychainStub.getUserKeyPair.withArgs(emailAddress).yieldsAsync(null, mockKeyPair); + initFoldersStub.yieldsAsync(); + + dao.init({ + account: account + }, function(err, keypair) { + expect(err).to.not.exist; + expect(keypair).to.exist; + expect(keychainStub.getUserKeyPair.calledOnce).to.be.true; + expect(initFoldersStub.calledOnce).to.be.true; + + done(); + }); + }); + + it('should fail when keychain errors', function(done) { + keychainStub.getUserKeyPair.yieldsAsync({}); + + dao.init({ + account: account + }, function(err, keypair) { + expect(err).to.exist; + expect(keypair).to.not.exist; + expect(keychainStub.getUserKeyPair.calledOnce).to.be.true; + expect(initFoldersStub.called).to.be.false; + + done(); + }); + }); + }); + + describe('#unlock', function() { + it('should unlock', function(done) { + pgpStub.getKeyParams.returns({ + _id: mockKeyPair.publicKey._id, + userId: emailAddress, + userIds: [{ + emailAddress: emailAddress + }] + }); + + pgpStub.importKeys.withArgs({ + passphrase: passphrase, + privateKeyArmored: mockKeyPair.privateKey.encryptedKey, + publicKeyArmored: mockKeyPair.publicKey.publicKey + }).yieldsAsync(); + pgpStub._privateKey = { + foo: 'bar' + }; + + dao.unlock({ + passphrase: passphrase, + keypair: mockKeyPair + }, function(err) { + expect(err).to.not.exist; + + expect(pgpStub.importKeys.calledOnce).to.be.true; + expect(dao._pgpbuilder._privateKey).to.equal(pgpStub._privateKey); + + done(); + }); + }); + + it('should generate a keypair and unlock', function(done) { + var keypair = { + keyId: 123, + publicKeyArmored: mockKeyPair.publicKey.publicKey, + privateKeyArmored: mockKeyPair.privateKey.encryptedKey + }; + + pgpStub.generateKeys.withArgs({ + emailAddress: emailAddress, + keySize: asymKeySize, + passphrase: passphrase + }).yieldsAsync(null, keypair); + + pgpStub.importKeys.withArgs({ + passphrase: passphrase, + privateKeyArmored: mockKeyPair.privateKey.encryptedKey, + publicKeyArmored: mockKeyPair.publicKey.publicKey + }).yieldsAsync(); + keychainStub.putUserKeyPair.withArgs().yieldsAsync(); + + dao.unlock({ + passphrase: passphrase + }, function(err) { + expect(err).to.not.exist; + + expect(pgpStub.generateKeys.calledOnce).to.be.true; + expect(pgpStub.importKeys.calledOnce).to.be.true; + expect(keychainStub.putUserKeyPair.calledOnce).to.be.true; + + done(); + }); + }); + + it('should fail when persisting fails', function(done) { + var keypair = { + keyId: 123, + publicKeyArmored: 'qwerty', + privateKeyArmored: 'asdfgh' + }; + pgpStub.generateKeys.yieldsAsync(null, keypair); + pgpStub.importKeys.withArgs().yieldsAsync(); + keychainStub.putUserKeyPair.yieldsAsync({}); + + dao.unlock({ + passphrase: passphrase + }, function(err) { + expect(err).to.exist; + + expect(pgpStub.generateKeys.calledOnce).to.be.true; + expect(pgpStub.importKeys.calledOnce).to.be.true; + expect(keychainStub.putUserKeyPair.calledOnce).to.be.true; + + done(); + }); + }); + + it('should fail when import fails', function(done) { + var keypair = { + keyId: 123, + publicKeyArmored: 'qwerty', + privateKeyArmored: 'asdfgh' + }; + + pgpStub.generateKeys.withArgs().yieldsAsync(null, keypair); + pgpStub.importKeys.withArgs().yieldsAsync({}); + + dao.unlock({ + passphrase: passphrase + }, function(err) { + expect(err).to.exist; + + expect(pgpStub.generateKeys.calledOnce).to.be.true; + expect(pgpStub.importKeys.calledOnce).to.be.true; + + done(); + }); + }); + + it('should fail when generation fails', function(done) { + pgpStub.generateKeys.yieldsAsync({}); + + dao.unlock({ + passphrase: passphrase + }, function(err) { + expect(err).to.exist; + + expect(pgpStub.generateKeys.calledOnce).to.be.true; + + done(); + }); + }); + }); + + describe('#openFolder', function() { + it('should open an imap mailbox', function(done) { + imapClientStub.selectMailbox.withArgs({ + path: inboxFolder.path + }).yieldsAsync(); + + dao.openFolder({ + folder: inboxFolder + }, function(err) { + expect(err).to.not.exist; + expect(imapClientStub.selectMailbox.calledOnce).to.be.true; + done(); + }); + }); + + it('should not open the virtual outbox folder in imap', function() { + dao.openFolder({ + folder: outboxFolder + }); + + expect(imapClientStub.selectMailbox.called).to.be.false; + }); + + it('should not do anything in offline mode', function(done) { + account.online = false; + + dao.openFolder({ + folder: inboxFolder + }, function(err) { + expect(err).to.exist; + expect(imapClientStub.selectMailbox.called).to.be.false; + done(); + }); + + }); + }); + + describe('#refreshFolder', function() { + var localListStub, mail; + + beforeEach(function() { + localListStub = sinon.stub(dao, '_localListMessages'); + mail = { + uid: 123, + unread: true + }; + }); + + it('should add messages from disk', function(done) { + localListStub.withArgs({ + folder: inboxFolder + }).yieldsAsync(null, [mail]); + + dao.refreshFolder({ + folder: inboxFolder + }, function(err) { + expect(err).to.not.exist; + expect(inboxFolder.count).to.equal(1); + expect(inboxFolder.messages).to.contain(mail); + + done(); + }); + }); + + it('should not add messages from disk', function(done) { + inboxFolder.messages = [mail]; + localListStub.withArgs({ + folder: inboxFolder + }).yieldsAsync(null, [mail]); + + dao.refreshFolder({ + folder: inboxFolder + }, function(err) { + expect(err).to.not.exist; + expect(inboxFolder.count).to.equal(1); + expect(inboxFolder.messages).to.contain(mail); + + done(); + }); + }); + + it('should remove messages from memory', function(done) { + inboxFolder.messages = [mail]; + localListStub.withArgs({ + folder: inboxFolder + }).yieldsAsync(null, []); + + dao.refreshFolder({ + folder: inboxFolder + }, function(err) { + expect(err).to.not.exist; + expect(inboxFolder.count).to.equal(0); + expect(inboxFolder.messages).to.be.empty; + + done(); + }); + }); + }); + + describe('#fetchMessages', function() { + var imapListStub, imapGetStub, imapDeleteStub, localStoreStub; + var opts, message, validUuid, corruptedUuid, verificationSubject; + var notified; + + beforeEach(function() { + imapListStub = sinon.stub(dao, '_imapListMessages'); + imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); + imapGetStub = sinon.stub(dao, '_getBodyParts'); + localStoreStub = sinon.stub(dao, '_localStoreMessages'); + + opts = { + folder: inboxFolder, + firstUid: 123, + lastUid: 123 + }; + message = { + uid: 123, + subject: 'asdasd', + unread: true, + bodyParts: [] + }; + validUuid = '9A858952-17EE-4273-9E74-D309EAFDFAFB'; + corruptedUuid = 'OMFG_FUCKING_BASTARD_UUID_FROM_HELL!'; + verificationSubject = "[whiteout] New public key uploaded"; + + notified = false; + dao.onIncomingMessage = function(newMessages) { + expect(newMessages).to.contain(message); + notified = true; + }; + }); + + it('should fetch message downstream', function(done) { + imapListStub.withArgs(opts).yieldsAsync(null, [message]); + + localStoreStub.withArgs({ + folder: inboxFolder, + emails: [message] + }).yieldsAsync(); + + dao.fetchMessages(opts, function(err) { + expect(err).to.not.exist; + expect(inboxFolder.messages).to.contain(message); + expect(notified).to.be.true; + expect(localStoreStub.calledOnce).to.be.true; + expect(imapListStub.calledOnce).to.be.true; + expect(account.busy).to.be.false; + + done(); + }); + }); + + it('should verify verification mails', function(done) { + message.subject = verificationSubject; + + imapListStub.withArgs(opts).yieldsAsync(null, [message]); + + imapGetStub.withArgs({ + folder: inboxFolder, + uid: message.uid, + bodyParts: message.bodyParts + }).yieldsAsync(null, [{ + type: 'text', + content: '' + cfg.cloudUrl + cfg.verificationUrl + validUuid + }]); + + keychainStub.verifyPublicKey.withArgs(validUuid).yieldsAsync(); + + imapDeleteStub.withArgs({ + folder: inboxFolder, + uid: message.uid + }).yieldsAsync(); + + dao.fetchMessages(opts, function(err) { + expect(err).to.not.exist; + expect(inboxFolder.messages).to.not.contain(message); + expect(notified).to.be.false; + expect(imapListStub.calledOnce).to.be.true; + expect(imapGetStub.calledOnce).to.be.true; + expect(keychainStub.verifyPublicKey.calledOnce).to.be.true; + expect(imapDeleteStub.calledOnce).to.be.true; + expect(localStoreStub.called).to.be.false; + done(); + }); + }); + + it('should not verify invalid verification mails', function(done) { + message.subject = verificationSubject; + + imapListStub.withArgs(opts).yieldsAsync(null, [message]); + + imapGetStub.withArgs({ + folder: inboxFolder, + uid: message.uid, + bodyParts: message.bodyParts + }).yieldsAsync(null, [{ + type: 'text', + content: '' + cfg.cloudUrl + cfg.verificationUrl + corruptedUuid + }]); + + localStoreStub.withArgs({ + folder: inboxFolder, + emails: [message] + }).yieldsAsync(); + + dao.fetchMessages(opts, function(err) { + expect(err).to.not.exist; + expect(inboxFolder.messages).to.contain(message); + expect(notified).to.be.true; + expect(imapListStub.calledOnce).to.be.true; + expect(imapGetStub.calledOnce).to.be.true; + expect(keychainStub.verifyPublicKey.called).to.be.false; + expect(imapDeleteStub.called).to.be.false; + expect(localStoreStub.calledOnce).to.be.true; + done(); + }); + }); + + it('should display verification mail when verification failed', function(done) { + message.subject = verificationSubject; + + imapListStub.withArgs(opts).yieldsAsync(null, [message]); + + imapGetStub.withArgs({ + folder: inboxFolder, + uid: message.uid, + bodyParts: message.bodyParts + }).yieldsAsync(null, [{ + type: 'text', + content: '' + cfg.cloudUrl + cfg.verificationUrl + validUuid + }]); + + keychainStub.verifyPublicKey.withArgs(validUuid).yieldsAsync({}); + + localStoreStub.withArgs({ + folder: inboxFolder, + emails: [message] + }).yieldsAsync(); + + + dao.fetchMessages(opts, function(err) { + expect(err).to.not.exist; + expect(inboxFolder.messages).to.contain(message); + expect(notified).to.be.true; + expect(imapListStub.calledOnce).to.be.true; + expect(imapGetStub.calledOnce).to.be.true; + expect(keychainStub.verifyPublicKey.calledOnce).to.be.true; + expect(imapDeleteStub.called).to.be.false; + expect(localStoreStub.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('#deleteMessage', function() { + var imapDeleteStub, localDeleteStub, message; + + beforeEach(function() { + message = { + uid: 1234 + }; + imapDeleteStub = sinon.stub(dao, '_imapDeleteMessage'); + localDeleteStub = sinon.stub(dao, '_localDeleteMessage'); + inboxFolder.messages = [message]; + outboxFolder.messages = [message]; + }); + + it('should delete from imap, local, memory', function(done) { + var deleteOpts = { + folder: inboxFolder, + uid: message.uid + }; + + imapDeleteStub.withArgs(deleteOpts).yieldsAsync(); + localDeleteStub.withArgs(deleteOpts).yieldsAsync(); + + dao.deleteMessage({ + folder: inboxFolder, + message: message + }, function(err) { + expect(err).to.not.exist; + expect(imapDeleteStub.calledOnce).to.be.true; + expect(localDeleteStub.calledOnce).to.be.true; + expect(inboxFolder.messages).to.not.contain(message); + + done(); + }); + }); + + it('should delete from local, memory', function(done) { + var deleteOpts = { + folder: inboxFolder, + uid: message.uid + }; + + localDeleteStub.withArgs(deleteOpts).yieldsAsync(); + + dao.deleteMessage({ + folder: inboxFolder, + message: message, + localOnly: true + }, function(err) { + expect(err).to.not.exist; + expect(imapDeleteStub.called).to.be.false; + expect(localDeleteStub.calledOnce).to.be.true; + expect(inboxFolder.messages).to.not.contain(message); + + done(); + }); + }); + + it('should delete from outbox from local, memory', function(done) { + var deleteOpts = { + folder: outboxFolder, + uid: message.uid + }; + + localDeleteStub.withArgs(deleteOpts).yieldsAsync(); + + dao.deleteMessage({ + folder: outboxFolder, + message: message + }, function(err) { + expect(err).to.not.exist; + expect(imapDeleteStub.called).to.be.false; + expect(localDeleteStub.calledOnce).to.be.true; + expect(outboxFolder.messages).to.not.contain(message); + + done(); + }); + }); + + it('should fail at delete from local', function(done) { + var deleteOpts = { + folder: inboxFolder, + uid: message.uid + }; + + imapDeleteStub.withArgs(deleteOpts).yieldsAsync(); + localDeleteStub.withArgs(deleteOpts).yieldsAsync({}); + + dao.deleteMessage({ + folder: inboxFolder, + message: message + }, function(err) { + expect(err).to.exist; + expect(imapDeleteStub.calledOnce).to.be.true; + expect(localDeleteStub.calledOnce).to.be.true; + expect(inboxFolder.messages).to.contain(message); + + done(); + }); + }); + + it('should fail at delete from imap', function(done) { + var deleteOpts = { + folder: inboxFolder, + uid: message.uid + }; + + imapDeleteStub.withArgs(deleteOpts).yieldsAsync({}); + + dao.deleteMessage({ + folder: inboxFolder, + message: message + }, function(err) { + expect(err).to.exist; + expect(imapDeleteStub.calledOnce).to.be.true; + expect(localDeleteStub.called).to.be.false; + expect(inboxFolder.messages).to.contain(message); + + done(); + }); + }); + + it('should fail at delete from imap in offline', function(done) { + account.online = false; + dao.deleteMessage({ + folder: inboxFolder, + message: message + }, function(err) { + expect(err).to.exist; + expect(imapDeleteStub.called).to.be.false; + expect(localDeleteStub.called).to.be.false; + expect(inboxFolder.messages).to.contain(message); + + done(); + }); + }); + }); + + describe('#setFlags', function() { + var imapMark, localListStub, localStoreStub, message; + + beforeEach(function() { + message = { + uid: 1234 + }; + imapMark = sinon.stub(dao, '_imapMark'); + localListStub = sinon.stub(dao, '_localListMessages'); + localStoreStub = sinon.stub(dao, '_localStoreMessages'); + inboxFolder.messages = [message]; + outboxFolder.messages = [message]; + }); + + it('should set flags for imap, disk, memory', function(done) { + imapMark.withArgs({ + folder: inboxFolder, + uid: message.uid, + unread: message.unread, + answered: message.answered + }).yieldsAsync(); + + localListStub.withArgs({ + folder: inboxFolder, + uid: message.uid + }).yieldsAsync(null, [message]); + + localStoreStub.withArgs({ + folder: inboxFolder, + emails: [message] + }).yieldsAsync(); + + dao.setFlags({ + folder: inboxFolder, + message: message + }, function(err) { + expect(err).to.not.exist; + expect(imapMark.calledOnce).to.be.true; + expect(localListStub.calledOnce).to.be.true; + expect(localStoreStub.calledOnce).to.be.true; + + done(); + }); + }); + + it('should set flags for outbox for disk, memory', function(done) { + localListStub.withArgs({ + folder: outboxFolder, + uid: message.uid + }).yieldsAsync(null, [message]); + + localStoreStub.withArgs({ + folder: outboxFolder, + emails: [message] + }).yieldsAsync(); + + dao.setFlags({ + folder: outboxFolder, + message: message + }, function(err) { + expect(err).to.not.exist; + expect(imapMark.called).to.be.false; + expect(localListStub.calledOnce).to.be.true; + expect(localStoreStub.calledOnce).to.be.true; + + done(); + }); + }); + + it('should set flags for disk, memory', function(done) { + localListStub.withArgs({ + folder: inboxFolder, + uid: message.uid + }).yieldsAsync(null, [message]); + + localStoreStub.withArgs({ + folder: inboxFolder, + emails: [message] + }).yieldsAsync(); + + dao.setFlags({ + folder: inboxFolder, + message: message, + localOnly: true + }, function(err) { + expect(err).to.not.exist; + expect(imapMark.called).to.be.false; + expect(localListStub.calledOnce).to.be.true; + expect(localStoreStub.calledOnce).to.be.true; + + done(); + }); + }); + + it('should fail to set flags for imap', function(done) { + imapMark.yieldsAsync({}); + localListStub.yieldsAsync(null, [message]); + localStoreStub.yieldsAsync(); + + dao.setFlags({ + folder: inboxFolder, + message: message + }, function(err) { + expect(err).to.exist; + expect(imapMark.calledOnce).to.be.true; + expect(localListStub.called).to.be.false; + expect(localStoreStub.called).to.be.false; + + done(); + }); + }); + it('should fail to set flags for imap in offline mode', function(done) { + account.online = false; + localListStub.yieldsAsync(null, [message]); + localStoreStub.yieldsAsync(); + + dao.setFlags({ + folder: inboxFolder, + message: message + }, function(err) { + expect(err).to.exist; + expect(imapMark.called).to.be.false; + expect(localListStub.called).to.be.false; + expect(localStoreStub.called).to.be.false; + + done(); + }); + }); + }); + + describe('#getBody', function() { + var localListStub, localStoreStub, imapGetStub, uid; + + beforeEach(function() { + uid = 12345, + localListStub = sinon.stub(dao, '_localListMessages'); + localStoreStub = sinon.stub(dao, '_localStoreMessages'); + imapGetStub = sinon.stub(dao, '_getBodyParts'); + }); + + it('should not do anything if the message already has content', function() { + var message = { + body: 'bender is great!' + }; + + dao.getBody({ + message: message + }); + + // should do nothing + }); + + it('should read an unencrypted body from the device', function(done) { + var message, body; + + body = 'bender is great! bender is great!'; + message = { + uid: uid + }; + + localListStub.withArgs({ + folder: inboxFolder, + uid: uid + }).yieldsAsync(null, [{ + bodyParts: [{ + type: 'text', + content: body + }] + }]); + + dao.getBody({ + message: message, + folder: inboxFolder + }, function(err, msg) { + expect(err).to.not.exist; + + expect(msg).to.equal(message); + expect(msg.body).to.equal(body); + expect(msg.loadingBody).to.be.false; + + expect(localListStub.calledOnce).to.be.true; + + done(); + }); + expect(message.loadingBody).to.be.true; + }); + + it('should read a pgp/mime from the device', function(done) { + var message, ct, pt; + + pt = 'bender is great!'; + ct = '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----'; + message = { + uid: uid, + encrypted: true + }; + + localListStub.withArgs({ + folder: inboxFolder, + uid: uid + }).yieldsAsync(null, [{ + bodyParts: [{ + type: 'text', + content: pt + }, { + type: 'encrypted', + content: ct + }] + }]); + + dao.getBody({ + message: message, + folder: inboxFolder + }, function(err, msg) { + expect(err).to.not.exist; + + expect(msg).to.equal(message); + expect(msg.body).to.equal(ct); + expect(msg.encrypted).to.be.true; + expect(message.loadingBody).to.be.false; + + expect(localListStub.calledOnce).to.be.true; + + done(); + }); + expect(message.loadingBody).to.be.true; + }); + + it('should read a pgp/inline from the device', function(done) { + var message, ct, pt; + + ct = '-----BEGIN PGP MESSAGE-----\nasdasdasd\n-----END PGP MESSAGE-----'; + pt = 'bla bla yadda yadda'; + message = { + uid: uid + }; + + localListStub.yieldsAsync(null, [{ + bodyParts: [{ + type: 'text', + content: pt + }, { + type: 'text', + content: ct + }, { + type: 'text', + content: pt + }] + }]); + + dao.getBody({ + message: message, + folder: inboxFolder + }, function(err, msg) { + expect(err).to.not.exist; + + expect(msg).to.equal(message); + expect(msg.body).to.equal(ct); + expect(msg.bodyParts[0].type).to.equal('encrypted'); + expect(msg.bodyParts[0].content).to.equal(ct); + expect(msg.encrypted).to.be.true; + expect(message.loadingBody).to.be.false; + + expect(localListStub.calledOnce).to.be.true; + + done(); + }); + expect(message.loadingBody).to.be.true; + }); + + it('should stream from imap and set plain text body', function(done) { + var message, body, uid; + + body = 'bender is great! bender is great!'; + uid = 1234; + message = { + uid: uid, + bodyParts: [{ + type: 'text' + }] + }; + + localListStub.withArgs({ + folder: inboxFolder, + uid: uid + }).yieldsAsync(null, [message]); + + localStoreStub.withArgs({ + folder: inboxFolder, + emails: [message] + }).yieldsAsync(); + + imapGetStub.withArgs({ + folder: inboxFolder, + uid: message.uid, + bodyParts: message.bodyParts + }).yieldsAsync(null, [{ + type: 'text', + content: body + }]); + + dao.getBody({ + message: message, + folder: inboxFolder + }, function(err, msg) { + expect(err).to.not.exist; + + expect(msg).to.equal(message); + expect(msg.body).to.equal(body); + expect(msg.loadingBody).to.be.false; + + expect(localListStub.calledOnce).to.be.true; + expect(imapGetStub.calledOnce).to.be.true; + expect(localStoreStub.calledOnce).to.be.true; + + done(); + }); + expect(message.loadingBody).to.be.true; + }); + + it('should stream from imap and set encrypted body', function(done) { + var message, ct, pt; + + pt = 'bender is great'; + ct = '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----'; + message = { + uid: uid, + encrypted: true, + bodyParts: [{ + type: 'text' + }, { + type: 'encrypted' + }] + }; + + localListStub.withArgs({ + folder: inboxFolder, + uid: uid + }).yieldsAsync(null, [message]); + + localStoreStub.withArgs({ + folder: inboxFolder, + emails: [message] + }).yieldsAsync(); + + imapGetStub.withArgs({ + folder: inboxFolder, + uid: message.uid, + bodyParts: message.bodyParts + }).yieldsAsync(null, [{ + type: 'text', + content: pt + }, { + type: 'encrypted', + content: ct + }]); + + + dao.getBody({ + message: message, + folder: inboxFolder + }, function(err, msg) { + expect(err).to.not.exist; + + expect(msg).to.equal(message); + expect(msg.body).to.equal(ct); + expect(msg.encrypted).to.be.true; + expect(msg.loadingBody).to.be.false; + + expect(localListStub.calledOnce).to.be.true; + expect(imapGetStub.calledOnce).to.be.true; + expect(localStoreStub.calledOnce).to.be.true; + + done(); + }); + expect(message.loadingBody).to.be.true; + }); + + it('fail to stream from imap due to error when persisting', function(done) { + var message = { + uid: uid, + bodyParts: [{ + type: 'text' + }] + }; + + localListStub.yieldsAsync(null, [message]); + localStoreStub.yieldsAsync({}); + imapGetStub.yieldsAsync(null, [{ + type: 'text', + content: 'bender is great! bender is great!' + }]); + + dao.getBody({ + message: message, + folder: inboxFolder + }, function(err, msg) { + expect(err).to.exist; + expect(msg).to.not.exist; + expect(localListStub.calledOnce).to.be.true; + expect(imapGetStub.calledOnce).to.be.true; + expect(localStoreStub.calledOnce).to.be.true; + + expect(message.loadingBody).to.be.false; + + done(); + }); + }); + + it('fail to stream from imap due to stream error', function(done) { + var message = { + uid: uid, + bodyParts: [{ + type: 'text' + }] + }; + + localListStub.yieldsAsync(null, [message]); + imapGetStub.yieldsAsync({}); + + dao.getBody({ + message: message, + folder: inboxFolder + }, function(err, msg) { + expect(err).to.exist; + expect(msg).to.not.exist; + expect(localListStub.calledOnce).to.be.true; + expect(imapGetStub.calledOnce).to.be.true; + expect(localStoreStub.called).to.be.false; + + expect(message.loadingBody).to.be.false; + + done(); + }); + }); + }); + + describe('#getAttachment', function() { + var imapGetStub, uid; + + beforeEach(function() { + uid = 123456; + imapGetStub = sinon.stub(dao, '_getBodyParts'); + }); + + it('should fetch an attachment from imap', function(done) { + var attmt = {}; + + imapGetStub.withArgs({ + folder: inboxFolder, + uid: uid, + bodyParts: [attmt] + }).yieldsAsync(null, [{ + content: 'CONTENT!!!' + }]); + + dao.getAttachment({ + folder: inboxFolder, + uid: uid, + attachment: attmt + }, function(err, fetchedAttmt) { + expect(err).to.not.exist; + expect(fetchedAttmt).to.equal(attmt); + expect(attmt.content).to.not.be.empty; + expect(imapGetStub.calledOnce).to.be.true; + + done(); + }); + }); + + it('should error during fetch', function(done) { + var attmt = {}; + + imapGetStub.yieldsAsync({}); + + dao.getAttachment({ + folder: inboxFolder, + uid: uid, + attachment: attmt + }, function(err, fetchedAttmt) { + expect(err).to.exist; + expect(fetchedAttmt).to.not.exist; + expect(imapGetStub.calledOnce).to.be.true; + + done(); + }); + }); + }); + + describe('#decryptBody', function() { + it('should do nothing when the message is not encrypted', function(done) { + var message = { + encrypted: false, + decrypted: true, + body: 'asd' + }; + + dao.decryptBody({ + message: message + }, done); + }); + + it('should do nothing when the message is already decrypted', function(done) { + var message = { + encrypted: true, + decrypted: true, + body: 'asd' + }; + + dao.decryptBody({ + message: message + }, done); + }); + + it('should do nothing when the message has no body', function(done) { + var message = { + encrypted: true, + decrypted: false, + body: '' + }; + + dao.decryptBody({ + message: message + }, done); + }); + + it('should do nothing when the message is decrypting', function(done) { + var message = { + encrypted: true, + decrypted: false, + body: 'asd', + decryptingBody: true + }; + + dao.decryptBody({ + message: message + }, done); + }); + + it('decrypt a pgp/mime message', function(done) { + var message, ct, pt, parsed; + + pt = 'bender is great'; + ct = '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----'; + parsed = 'bender! bender! bender!'; + message = { + from: [{ + address: 'asdasdasd' + }], + body: ct, + encrypted: true, + bodyParts: [{ + type: 'encrypted', + content: ct + }] + }; + + keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey); + pgpStub.decrypt.withArgs(ct, mockKeyPair.publicKey.publicKey).yieldsAsync(null, pt); + parseStub.withArgs({ + bodyParts: [{ + type: 'encrypted', + content: ct, + raw: pt + }] + }).yieldsAsync(null, [{ + type: 'encrypted', + content: [{ + type: 'text', + content: parsed + }] + }]); + + dao.decryptBody({ + message: message + }, function(error, msg) { + expect(error).to.not.exist; + expect(msg).to.equal(message); + expect(message.decrypted).to.be.true; + expect(message.body).to.equal(parsed); + expect(message.decryptingBody).to.be.false; + expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true; + expect(pgpStub.decrypt.calledOnce).to.be.true; + expect(parseStub.calledOnce).to.be.true; + + done(); + }); + + expect(message.decryptingBody).to.be.true; + }); + + it('decrypt a pgp/inline message', function(done) { + var message, ct, pt; + + pt = 'bender is great'; + ct = '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----'; + message = { + from: [{ + address: 'asdasdasd' + }], + body: ct, + encrypted: true, + bodyParts: [{ + type: 'encrypted', + content: ct, + _isPgpInline: true + }] + }; + + keychainStub.getReceiverPublicKey.withArgs(message.from[0].address).yieldsAsync(null, mockKeyPair.publicKey); + pgpStub.decrypt.withArgs(ct, mockKeyPair.publicKey.publicKey).yieldsAsync(null, pt); + + dao.decryptBody({ + message: message + }, function(error, msg) { + expect(error).to.not.exist; + + expect(msg).to.equal(message); + expect(message.decrypted).to.be.true; + expect(message.body).to.equal(pt); + expect(message.decryptingBody).to.be.false; + expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true; + expect(pgpStub.decrypt.calledOnce).to.be.true; + expect(parseStub.called).to.be.false; + + done(); + }); + + expect(message.decryptingBody).to.be.true; + }); + + it('should fail during decryption message', function(done) { + var message = { + from: [{ + address: 'asdasdasd' + }], + body: 'asdjafuad', + encrypted: true, + bodyParts: [{ + type: 'encrypted', + content: '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----' + }] + }; + + keychainStub.getReceiverPublicKey.yieldsAsync(null, mockKeyPair.publicKey); + pgpStub.decrypt.yieldsAsync({ + errMsg: 'asd' + }); + + dao.decryptBody({ + message: message + }, function(error, msg) { + expect(error).to.not.exist; + expect(msg.body).to.equal('asd'); + expect(msg).to.exist; + expect(message.decryptingBody).to.be.false; + expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true; + expect(pgpStub.decrypt.calledOnce).to.be.true; + expect(parseStub.called).to.be.false; + + done(); + }); + }); + + it('should fail during key export', function(done) { + var message = { + from: [{ + address: 'asdasdasd' + }], + encrypted: true, + body: 'asdjafuad', + bodyParts: [{ + type: 'encrypted', + content: '-----BEGIN PGP MESSAGE-----asdasdasd-----END PGP MESSAGE-----' + }] + }; + + keychainStub.getReceiverPublicKey.yieldsAsync({}); + + dao.decryptBody({ + message: message + }, function(error, msg) { + expect(error).to.exist; + expect(msg).to.not.exist; + expect(message.decryptingBody).to.be.false; + expect(keychainStub.getReceiverPublicKey.calledOnce).to.be.true; + expect(pgpStub.decrypt.called).to.be.false; + expect(parseStub.called).to.be.false; + + done(); + }); + }); + }); + + describe('#sendEncrypted', function() { + var publicKeys = ["PUBLIC KEY"], + dummyMail = { + publicKeysArmored: publicKeys + }; + + it('should send encrypted', function(done) { + pgpMailerStub.send.withArgs({ + encrypt: true, + cleartextMessage: str.message + str.signature, + mail: dummyMail, + smtpclient: undefined, + publicKeysArmored: publicKeys + }).yieldsAsync(); + + dao.sendEncrypted({ + email: dummyMail + }, function(err) { + expect(err).to.not.exist; + + expect(pgpMailerStub.send.calledOnce).to.be.true; + + done(); + }); + }); + + it('should not send when pgpmailer fails', function(done) { + pgpMailerStub.send.yieldsAsync({}); + + dao.sendEncrypted({ + email: dummyMail + }, function(err) { + expect(err).to.exist; + + expect(pgpMailerStub.send.calledOnce).to.be.true; + + done(); + }); + }); + + it('should not send in offline mode', function(done) { + account.online = false; + + dao.sendEncrypted({}, function(err) { + expect(err).to.exist; + expect(pgpMailerStub.send.called).to.be.false; + done(); + }); + }); + + }); + + describe('#sendPlaintext', function() { + var dummyMail = {}; + + it('should send in the plain', function(done) { + pgpMailerStub.send.withArgs({ + smtpclient: undefined, + mail: dummyMail + }).yieldsAsync(); + + dao.sendPlaintext({ + email: dummyMail + }, function(err) { + expect(err).to.not.exist; + expect(pgpMailerStub.send.calledOnce).to.be.true; + done(); + }); + }); + + it('should not send due to error', function(done) { + pgpMailerStub.send.yieldsAsync({}); + + dao.sendPlaintext({ + email: dummyMail + }, function(err) { + expect(err).to.exist; + expect(pgpMailerStub.send.calledOnce).to.be.true; + done(); + }); + }); + + it('should not send in offline mode', function(done) { + account.online = false; + + dao.sendPlaintext({}, function(err) { + expect(err).to.exist; + expect(pgpMailerStub.send.called).to.be.false; + done(); + }); + }); + }); + + describe('#encrypt', function() { + it('should encrypt', function(done) { + pgpBuilderStub.encrypt.yieldsAsync(); + + dao.encrypt({}, function() { + expect(pgpBuilderStub.encrypt.calledOnce).to.be.true; + done(); + }); + }); + }); + }); + + describe('event handlers', function() { + + describe('#onConnect', function() { + var initFoldersStub; + + beforeEach(function() { + initFoldersStub = sinon.stub(dao, '_initFoldersFromImap'); + delete dao._imapClient; + delete dao._pgpMailer; + }); + + it('should connect', function(done) { + inboxFolder.messages = [{ + uid: 123, + modseq: 123 + }]; + imapClientStub.login.yieldsAsync(); + imapClientStub.listenForChanges.yieldsAsync(); + initFoldersStub.yieldsAsync(); + + dao.onConnect({ + imapClient: imapClientStub, + pgpMailer: pgpMailerStub + }, function(err) { + + expect(err).to.not.exist; + expect(imapClientStub.login.calledOnce).to.be.true; + expect(initFoldersStub.calledOnce).to.be.true; + expect(imapClientStub.mailboxCache).to.deep.equal({ + 'INBOX': { + exists: 123, + uidNext: 124, + uidlist: [123], + highestModseq: 123 + } + }); + + done(); + }); + }); + }); + + describe('#onDisconnect', function() { + it('should discard imapClient and pgpMailer', function() { + dao.onDisconnect(); + + expect(dao._account.online).to.be.false; + expect(dao._imapClient).to.not.exist; + expect(dao._pgpMailer).to.not.exist; + }); + }); + + describe('#_onSyncUpdate', function() { + var fetchMessagesStub, deleteMessagesStub, setFlagsStub, msgs; + + beforeEach(function() { + msgs = [{ + uid: 5, + flags: ['\\Answered', '\\Seen'] + }]; + inboxFolder.messages = msgs; + fetchMessagesStub = sinon.stub(dao, 'fetchMessages'); + deleteMessagesStub = sinon.stub(dao, 'deleteMessage'); + setFlagsStub = sinon.stub(dao, 'setFlags'); + }); + + it('should get new message', function(done) { + fetchMessagesStub.withArgs({ + folder: inboxFolder, + firstUid: 1, + lastUid: 3 + }).yieldsAsync(); + + dao.onError = function(err) { + expect(err).to.not.exist; + expect(fetchMessagesStub.calledOnce).to.be.true; + done(); + }; + + dao._onSyncUpdate({ + type: 'new', + path: inboxFolder.path, + list: [1, 3] + }); + }); + + it('should delete message', function(done) { + deleteMessagesStub.withArgs({ + folder: inboxFolder, + message: msgs[0], + localOnly: true + }).yieldsAsync(); + + dao.onError = function(err) { + expect(err).to.not.exist; + expect(deleteMessagesStub.calledOnce).to.be.true; + done(); + }; + + dao._onSyncUpdate({ + type: 'deleted', + path: inboxFolder.path, + list: [5] + }); + }); + + it('should fetch flags', function(done) { + setFlagsStub.withArgs({ + folder: inboxFolder, + message: msgs[0], + localOnly: true + }).yieldsAsync(); + + dao.onError = function(err) { + expect(err).to.not.exist; + expect(setFlagsStub.calledOnce).to.be.true; + done(); + }; + + dao._onSyncUpdate({ + type: 'messages', + path: inboxFolder.path, + list: msgs + }); + }); + }); + }); + + + describe('internal API', function() { + describe('#_initFoldersFromDisk', function() { + beforeEach(function() { + sinon.stub(dao, 'refreshFolder'); + }); + + it('should initialize from disk if offline and not refresh folder', function(done) { + devicestorageStub.listItems.withArgs('folders').yieldsAsync(null, [ + [inboxFolder] + ]); + dao.refreshFolder.withArgs({ + folder: inboxFolder + }).yieldsAsync(); + + dao._initFoldersFromDisk(function(err) { + expect(err).to.not.exist; + expect(devicestorageStub.listItems.calledOnce).to.be.true; + expect(dao.refreshFolder.called).to.be.false; + done(); + }); + }); + + it('should initialize from disk if offline and refresh folder', function(done) { + delete inboxFolder.messages; + devicestorageStub.listItems.withArgs('folders').yieldsAsync(null, [ + [inboxFolder] + ]); + dao.refreshFolder.withArgs({ + folder: inboxFolder + }).yieldsAsync(); + + dao._initFoldersFromDisk(function(err) { + expect(err).to.not.exist; + expect(devicestorageStub.listItems.calledOnce).to.be.true; + expect(dao.refreshFolder.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('#_initFoldersFromImap', function() { + beforeEach(function() { + sinon.stub(dao, 'refreshFolder'); + }); + + it('should initialize from imap if online', function(done) { + account.folders = []; + imapClientStub.listWellKnownFolders.yieldsAsync(null, { + inbox: inboxFolder, + sent: sentFolder, + drafts: draftsFolder, + trash: trashFolder + }); + devicestorageStub.storeList.withArgs(sinon.match(function(arg) { + expect(arg[0][0]).to.deep.equal(inboxFolder); + expect(arg[0][1]).to.deep.equal(sentFolder); + expect(arg[0][2].path).to.deep.equal(outboxFolder.path); + expect(arg[0][2].type).to.deep.equal(outboxFolder.type); + expect(arg[0][3]).to.deep.equal(draftsFolder); + expect(arg[0][4]).to.deep.equal(trashFolder); + return true; + }), 'folders').yieldsAsync(); + + dao.refreshFolder.yieldsAsync(); + + dao._initFoldersFromImap(function(err) { + expect(err).to.not.exist; + expect(imapClientStub.listWellKnownFolders.calledOnce).to.be.true; + expect(devicestorageStub.storeList.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('#_imapMark', function() { + it('should flag a mail', function(done) { + imapClientStub.updateFlags.withArgs({ + path: inboxFolder.path, + folder: inboxFolder, + uid: 1, + unread: false, + answered: false + }).yieldsAsync(); + + dao._imapMark({ + folder: inboxFolder, + uid: 1, + unread: false, + answered: false + }, function(err) { + expect(err).to.not.exist; + expect(imapClientStub.updateFlags.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('#_imapDeleteMessage', function() { + var uid = 1337; + + it('should fail when disconnected', function(done) { + dao._account.online = false; + + dao._imapDeleteMessage({}, function(err) { + expect(err.code).to.equal(42); + done(); + }); + }); + + it('should move to trash', function(done) { + imapClientStub.moveMessage.withArgs({ + path: inboxFolder.path, + uid: uid, + destination: trashFolder.path + }).yieldsAsync(); + + dao._imapDeleteMessage({ + folder: inboxFolder, + uid: uid + }, done); + }); + + it('should purge message', function(done) { + imapClientStub.deleteMessage.withArgs({ + path: trashFolder.path, + uid: uid + }).yieldsAsync(); + + dao._imapDeleteMessage({ + folder: trashFolder, + uid: uid + }, done); + }); + }); + + describe('#_imapListMessages', function() { + var firstUid = 1337, + lastUid = 1339; + + it('should list messages', function(done) { + imapClientStub.listMessages.withArgs({ + folder: inboxFolder, + path: inboxFolder.path, + firstUid: firstUid, + lastUid: lastUid + }).yieldsAsync(null, []); + + dao._imapListMessages({ + folder: inboxFolder, + firstUid: firstUid, + lastUid: lastUid + }, function(err, msgs) { + expect(err).to.not.exist; + expect(msgs).to.exist; + + expect(imapClientStub.listMessages.calledOnce).to.be.true; + + done(); + }); + }); + + it('should fail when listMessages fails', function(done) { + imapClientStub.listMessages.yieldsAsync({}); + + dao._imapListMessages({ + folder: inboxFolder, + firstUid: firstUid, + lastUid: lastUid + }, function(err, msgs) { + expect(err).to.exist; + expect(msgs).to.not.exist; + expect(imapClientStub.listMessages.calledOnce).to.be.true; + + done(); + }); + }); + + it('should fail when disconnected', function(done) { + dao._account.online = false; + + dao._imapListMessages({}, function(err) { + expect(err.code).to.equal(42); + done(); + }); + }); + }); + + describe('#_getBodyParts', function() { + it('should get bodyParts', function(done) { + imapClientStub.getBodyParts.withArgs({ + folder: inboxFolder, + path: inboxFolder.path, + uid: 123, + bodyParts: [] + }).yieldsAsync(null, {}); + parseStub.yieldsAsync(null, []); + + dao._getBodyParts({ + folder: inboxFolder, + uid: 123, + bodyParts: [] + }, function(err, parts) { + expect(err).to.not.exist; + expect(parts).to.exist; + + expect(imapClientStub.getBodyParts.calledOnce).to.be.true; + expect(parseStub.calledOnce).to.be.true; + + done(); + }); + }); + + it('should fail when getBody fails', function(done) { + imapClientStub.getBodyParts.yieldsAsync({}); + + dao._getBodyParts({ + folder: inboxFolder, + uid: 123, + bodyParts: [] + }, function(err, msg) { + expect(err).to.exist; + expect(msg).to.not.exist; + + expect(imapClientStub.getBodyParts.calledOnce).to.be.true; + expect(parseStub.called).to.be.false; + + done(); + }); + }); + + it('should fail when disconnected', function(done) { + dao._account.online = false; + + dao._getBodyParts({}, function(err) { + expect(err.code).to.equal(42); + done(); + }); + }); + }); + + describe('#_localListMessages', function() { + var uid = 123; + + it('should list without uid', function(done) { + devicestorageStub.listItems.withArgs('email_' + inboxFolder.path, 0, null).yieldsAsync(); + + dao._localListMessages({ + folder: inboxFolder + }, done); + }); + + it('should list with uid', function(done) { + devicestorageStub.listItems.withArgs('email_' + inboxFolder.path + '_' + uid, 0, null).yieldsAsync(); + + dao._localListMessages({ + folder: inboxFolder, + uid: uid + }, done); + }); + + }); + + describe('#_localStoreMessages', function() { + it('should store messages', function(done) { + devicestorageStub.storeList.withArgs([{}], 'email_' + inboxFolder.path).yieldsAsync(); + + dao._localStoreMessages({ + folder: inboxFolder, + emails: [{}] + }, done); + }); + }); + + describe('#_localDeleteMessage', function() { + var uid = 1337; + + it('should delete message', function(done) { + devicestorageStub.removeList.withArgs('email_' + inboxFolder.path + '_' + uid).yieldsAsync(); + + dao._localDeleteMessage({ + folder: inboxFolder, + uid: uid + }, done); + }); + + it('should fail when uid is missing', function(done) { + dao._localDeleteMessage({ + folder: inboxFolder + }, function(err) { + expect(err).to.exist; + done(); + }); + }); + + }); + }); + }); }); \ No newline at end of file diff --git a/test/unit/forge-test.js b/test/unit/forge-test.js deleted file mode 100644 index 36ad9db..0000000 --- a/test/unit/forge-test.js +++ /dev/null @@ -1,42 +0,0 @@ -define(['node-forge', 'cryptoLib/util', 'test/test-data'], function(forge, util, testData) { - 'use strict'; - - module("Forge Crypto"); - - var forgeRsaTest = { - keySize: 1024, - testMessage: '06a9214036b8a15b512e03d534120006' - }; - - var forgeAesTest = { - keySize: 128, - testMessage: testData.generateBigString(1000) - }; - - test("SHA-1 Hash", 1, function() { - var sha1 = forge.md.sha1.create(); - sha1.update(forgeAesTest.testMessage); - var digest = sha1.digest().toHex(); - ok(digest, digest); - }); - - test("SHA-256 Hash", 1, function() { - forgeRsaTest.md = forge.md.sha256.create(); - forgeRsaTest.md.update(forgeAesTest.testMessage); - var digest = forgeRsaTest.md.digest().toHex(); - ok(digest, digest); - }); - - test("HMAC SHA-256", 1, function() { - var key = util.base642Str(util.random(forgeAesTest.keySize)); - var iv = util.base642Str(util.random(forgeAesTest.keySize)); - - var hmac = forge.hmac.create(); - hmac.start('sha256', key); - hmac.update(iv); - hmac.update(forgeAesTest.testMessage); - var digest = hmac.digest().toHex(); - - ok(digest, digest); - }); -}); \ No newline at end of file diff --git a/test/unit/index.html b/test/unit/index.html index 54ceadf..8a0094a 100644 --- a/test/unit/index.html +++ b/test/unit/index.html @@ -1,17 +1,19 @@ - + JavaScript Unit Tests - + + -
-
+
- - + + + + - \ No newline at end of file + diff --git a/test/new-unit/invitation-dao-test.js b/test/unit/invitation-dao-test.js similarity index 100% rename from test/new-unit/invitation-dao-test.js rename to test/unit/invitation-dao-test.js diff --git a/test/unit/keychain-dao-test.js b/test/unit/keychain-dao-test.js index c29d8c8..be19cef 100644 --- a/test/unit/keychain-dao-test.js +++ b/test/unit/keychain-dao-test.js @@ -1,92 +1,1373 @@ -define(['js/dao/keychain-dao', 'js/dao/lawnchair-dao'], function(KeychainDAO, LawnchairDAO) { - 'use strict'; +define(function(require) { + 'use strict'; - module("Keychain DAO"); + var LawnchairDAO = require('js/dao/lawnchair-dao'), + PublicKeyDAO = require('js/dao/publickey-dao'), + KeychainDAO = require('js/dao/keychain-dao'), + PrivateKeyDAO = require('js/dao/privatekey-dao'), + Crypto = require('js/crypto/crypto'), + PGP = require('js/crypto/pgp'), + expect = chai.expect; - var jsonDao, - keychaindaoTest = { - user: 'keychaindao_test@example.com', - password: 'Password', - keySize: 128, - ivSize: 128, - rsaKeySize: 512 - }; + var testUser = 'test@example.com'; - asyncTest("Init", 2, function() { + describe('Keychain DAO unit tests', function() { - // stubbing - var pubkeyDaoStub = { - put: function(pk, callback) { - callback(); - } - }; + var keychainDao, lawnchairDaoStub, pubkeyDaoStub, privkeyDaoStub, cryptoStub, pgpStub; - // module instancing - jsonDao = new LawnchairDAO(); - keychaindaoTest.keychainDao = new KeychainDAO(jsonDao, pubkeyDaoStub); - ok(keychaindaoTest.keychainDao); + beforeEach(function() { + lawnchairDaoStub = sinon.createStubInstance(LawnchairDAO); + pubkeyDaoStub = sinon.createStubInstance(PublicKeyDAO); + privkeyDaoStub = sinon.createStubInstance(PrivateKeyDAO); + cryptoStub = sinon.createStubInstance(Crypto); + pgpStub = sinon.createStubInstance(PGP); + keychainDao = new KeychainDAO(lawnchairDaoStub, pubkeyDaoStub, privkeyDaoStub, cryptoStub, pgpStub); + }); - // init and clear db before test - jsonDao.init(keychaindaoTest.user, function() { - jsonDao.clear(function() { - ok(true, 'cleared db'); + afterEach(function() {}); - start(); - }); - }); - }); + describe('verify public key', function() { + it('should verify public key', function(done) { + var uuid = 'asdfasdfasdfasdf'; + pubkeyDaoStub.verify.yields(); - asyncTest("Put User Keypair", 1, function() { + keychainDao.verifyPublicKey(uuid, function() { + expect(pubkeyDaoStub.verify.calledWith(uuid)).to.be.true; + done(); + }); + }); + }); - keychaindaoTest.keypair = { - publicKey: { - _id: '123', - userId: keychaindaoTest.user, - publicKey: 'asdf' - }, - privateKey: { - _id: '123', - userId: keychaindaoTest.user, - encryptedKey: 'qwer', - iv: 'yxvc' - } - }; + describe('listLocalPublicKeys', function() { + it('should work', function(done) { + lawnchairDaoStub.list.withArgs('publickey', 0, null).yields(); - keychaindaoTest.keychainDao.putUserKeyPair(keychaindaoTest.keypair, function(err) { - ok(!err); + keychainDao.listLocalPublicKeys(function() { + expect(lawnchairDaoStub.list.callCount).to.equal(1); + done(); + }); + }); + }); - start(); - }); - }); + describe('removeLocalPublicKey', function() { + it('should work', function(done) { + var id = 'asdf'; - asyncTest("Get User Keypair", 2, function() { - keychaindaoTest.keychainDao.getUserKeyPair(keychaindaoTest.user, function(err, keypair) { - ok(!err); - ok(keypair && keypair.publicKey && keypair.privateKey); + lawnchairDaoStub.remove.withArgs('publickey_' + id).yields(); - start(); - }); - }); + keychainDao.removeLocalPublicKey(id, function() { + expect(lawnchairDaoStub.remove.callCount).to.equal(1); + done(); + }); + }); + }); - asyncTest("Get Public Keys", 2, function() { - var pubkeyIds = [{ - _id: keychaindaoTest.keypair.publicKey._id - }]; - keychaindaoTest.keychainDao.getPublicKeys(pubkeyIds, function(err, pubkeys) { - ok(!err); - deepEqual(pubkeys[0], keychaindaoTest.keypair.publicKey, "Fetch public key"); + describe('refreshKeyForUserId', function() { + var getPubKeyStub, + oldKey = { + _id: 123 + }, + newKey = { + _id: 456 + }, + importedKey = { + _id: 789, + imported: true + }; - start(); - }); - }); + beforeEach(function() { + getPubKeyStub = sinon.stub(keychainDao, 'getReceiverPublicKey'); + }); - asyncTest("Get User Keypair", 2, function() { - keychaindaoTest.keychainDao.getReceiverPublicKey(keychaindaoTest.user, function(err, pubkey) { - ok(!err); - ok(pubkey && pubkey.publicKey); + afterEach(function() { + keychainDao.getReceiverPublicKey.restore(); + delete keychainDao.requestPermissionForKeyUpdate; + }); - start(); - }); - }); + it('should not find a key', function(done) { + getPubKeyStub.yields(); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.not.exist; + + done(); + }); + }); + + it('should not update the key when up to date', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields(null, oldKey); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.to.equal(oldKey); + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + + + done(); + }); + }); + + it('should update key', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields(); + pubkeyDaoStub.getByUserId.withArgs(testUser).yields(null, newKey); + keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { + expect(opts.userId).to.equal(testUser); + expect(opts.newKey).to.equal(newKey); + cb(true); + }; + lawnchairDaoStub.remove.withArgs('publickey_' + oldKey._id).yields(); + lawnchairDaoStub.persist.withArgs('publickey_' + newKey._id, newKey).yields(); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.equal(newKey); + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + expect(lawnchairDaoStub.remove.calledOnce).to.be.true; + expect(lawnchairDaoStub.persist.calledOnce).to.be.true; + + done(); + }); + }); + + it('should remove key', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields(); + pubkeyDaoStub.getByUserId.withArgs(testUser).yields(); + keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { + expect(opts.userId).to.equal(testUser); + expect(opts.newKey).to.not.exist; + cb(true); + }; + lawnchairDaoStub.remove.withArgs('publickey_' + oldKey._id).yields(); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.not.exist; + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + expect(lawnchairDaoStub.remove.calledOnce).to.be.true; + expect(lawnchairDaoStub.persist.called).to.be.false; + + done(); + }); + }); + + it('should go offline while fetching new key', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields(); + pubkeyDaoStub.getByUserId.withArgs(testUser).yields({ + code: 42 + }); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.to.equal(oldKey); + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + expect(lawnchairDaoStub.remove.called).to.be.false; + expect(lawnchairDaoStub.persist.called).to.be.false; + + done(); + }); + }); + + it('should not remove old key on user rejection', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields(); + pubkeyDaoStub.getByUserId.withArgs(testUser).yields(null, newKey); + keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { + expect(opts.userId).to.equal(testUser); + expect(opts.newKey).to.exist; + cb(false); + }; + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.equal(oldKey); + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + expect(lawnchairDaoStub.remove.called).to.be.false; + expect(lawnchairDaoStub.persist.called).to.be.false; + + done(); + }); + }); + + it('should not remove manually imported key', function(done) { + getPubKeyStub.yields(null, importedKey); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.equal(importedKey); + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.false; + + done(); + }); + }); + + it('should update not the key when offline', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields({ + code: 42 + }); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.to.equal(oldKey); + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.called).to.be.false; + expect(lawnchairDaoStub.remove.called).to.be.false; + expect(lawnchairDaoStub.persist.called).to.be.false; + + done(); + }); + }); + + it('should error while persisting new key', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields(); + pubkeyDaoStub.getByUserId.withArgs(testUser).yields(null, newKey); + keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { + expect(opts.userId).to.equal(testUser); + expect(opts.newKey).to.equal(newKey); + cb(true); + }; + lawnchairDaoStub.remove.withArgs('publickey_' + oldKey._id).yields(); + lawnchairDaoStub.persist.yields({}); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.exist; + expect(key).to.not.exist; + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + expect(lawnchairDaoStub.remove.calledOnce).to.be.true; + expect(lawnchairDaoStub.persist.calledOnce).to.be.true; + + done(); + }); + }); + + it('should error while deleting old key', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields(); + pubkeyDaoStub.getByUserId.withArgs(testUser).yields(); + keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { + expect(opts.userId).to.equal(testUser); + cb(true); + }; + lawnchairDaoStub.remove.yields({}); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.exist; + expect(key).to.not.exist; + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + expect(lawnchairDaoStub.remove.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + expect(lawnchairDaoStub.persist.called).to.be.false; + + done(); + }); + }); + + it('should error while persisting new key', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields(); + pubkeyDaoStub.getByUserId.withArgs(testUser).yields(null, newKey); + keychainDao.requestPermissionForKeyUpdate = function(opts, cb) { + expect(opts.userId).to.equal(testUser); + expect(opts.newKey).to.equal(newKey); + cb(true); + }; + lawnchairDaoStub.remove.withArgs('publickey_' + oldKey._id).yields(); + lawnchairDaoStub.persist.yields({}); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.exist; + expect(key).to.not.exist; + + expect(getPubKeyStub.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + expect(lawnchairDaoStub.remove.calledOnce).to.be.true; + expect(lawnchairDaoStub.persist.calledOnce).to.be.true; + + done(); + }); + }); + + it('should error when get failed', function(done) { + getPubKeyStub.yields(null, oldKey); + pubkeyDaoStub.get.withArgs(oldKey._id).yields({}); + + keychainDao.refreshKeyForUserId(testUser, function(err, key) { + expect(err).to.exist; + expect(key).to.not.exist; + + done(); + }); + }); + }); + + describe('lookup public key', function() { + it('should fail', function(done) { + keychainDao.lookupPublicKey(undefined, function(err, key) { + expect(err).to.exist; + expect(key).to.not.exist; + done(); + }); + }); + + it('should fail', function(done) { + lawnchairDaoStub.read.yields(42); + + keychainDao.lookupPublicKey('12345', function(err, key) { + expect(err).to.exist; + expect(key).to.not.exist; + expect(lawnchairDaoStub.read.calledOnce).to.be.true; + done(); + }); + }); + + it('should work from local storage', function(done) { + lawnchairDaoStub.read.yields(null, { + _id: '12345', + publicKey: 'asdf' + }); + + keychainDao.lookupPublicKey('12345', function(err, key) { + expect(err).to.not.exist; + expect(key).to.exist; + expect(lawnchairDaoStub.read.calledOnce).to.be.true; + done(); + }); + }); + + it('should work from cloud', function(done) { + lawnchairDaoStub.read.yields(); + pubkeyDaoStub.get.yields(null, { + _id: '12345', + publicKey: 'asdf' + }); + lawnchairDaoStub.persist.yields(); + + keychainDao.lookupPublicKey('12345', function(err, key) { + expect(err).to.not.exist; + expect(key).to.exist; + expect(key._id).to.equal('12345'); + expect(lawnchairDaoStub.read.calledOnce).to.be.true; + expect(pubkeyDaoStub.get.calledOnce).to.be.true; + expect(lawnchairDaoStub.persist.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('get public keys by id', function() { + it('should fail', function(done) { + keychainDao.getPublicKeys([], function(err, keys) { + expect(err).to.not.exist; + expect(keys.length).to.equal(0); + done(); + }); + }); + + it('should fail', function(done) { + lawnchairDaoStub.read.yields(42); + + var ids = [{ + _id: '12345' + }]; + keychainDao.getPublicKeys(ids, function(err, keys) { + expect(err).to.exist; + expect(keys).to.not.exist; + expect(lawnchairDaoStub.read.calledOnce).to.be.true; + done(); + }); + }); + + it('should work from local storage', function(done) { + lawnchairDaoStub.read.yields(null, { + _id: '12345', + publicKey: 'asdf' + }); + + var ids = [{ + _id: '12345' + }]; + keychainDao.getPublicKeys(ids, function(err, keys) { + expect(err).to.not.exist; + expect(keys.length).to.equal(1); + expect(keys[0]._id).to.equal('12345'); + expect(lawnchairDaoStub.read.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('get receiver public key', function() { + it('should fail due to error in lawnchair list', function(done) { + lawnchairDaoStub.list.yields(42); + + keychainDao.getReceiverPublicKey(testUser, function(err, key) { + expect(err).to.exist; + expect(key).to.not.exist; + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + done(); + }); + }); + + it('should work from lawnchair list', function(done) { + lawnchairDaoStub.list.yields(null, [{ + _id: '12345', + userId: testUser, + publicKey: 'asdf' + }]); + + keychainDao.getReceiverPublicKey(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.exist; + expect(key._id).to.equal('12345'); + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + done(); + }); + }); + + it('should work for keys with secondary userIds', function(done) { + lawnchairDaoStub.list.yields(null, [{ + _id: '12345', + userId: 'not testUser', + userIds: [{ + emailAddress: testUser + }], + publicKey: 'asdf' + }]); + + keychainDao.getReceiverPublicKey(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.exist; + expect(key._id).to.equal('12345'); + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + done(); + }); + }); + + it('should fail due to error in pubkey dao', function(done) { + lawnchairDaoStub.list.yields(null, []); + pubkeyDaoStub.getByUserId.yields({}); + + keychainDao.getReceiverPublicKey(testUser, function(err, key) { + expect(err).to.exist; + expect(key).to.not.exist; + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + done(); + }); + }); + + it('should work from pubkey dao with empty result', function(done) { + lawnchairDaoStub.list.yields(null, []); + pubkeyDaoStub.getByUserId.yields(); + + keychainDao.getReceiverPublicKey(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.not.exist; + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + done(); + }); + }); + + it('should work from pubkey dao', function(done) { + lawnchairDaoStub.list.yields(null, []); + pubkeyDaoStub.getByUserId.yields(null, { + _id: '12345', + publicKey: 'asdf' + }); + lawnchairDaoStub.persist.yields(); + + keychainDao.getReceiverPublicKey(testUser, function(err, key) { + expect(err).to.not.exist; + expect(key).to.exist; + expect(key._id).to.equal('12345'); + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + expect(lawnchairDaoStub.persist.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('get user key pair', function() { + it('should work if local keys are already present', function(done) { + lawnchairDaoStub.list.yields(null, [{ + _id: '12345', + userId: testUser, + publicKey: 'asdf' + }]); + lawnchairDaoStub.read.yields(null, { + _id: '12345', + publicKey: 'asdf', + encryptedKey: 'qwer' + }); + + keychainDao.getUserKeyPair(testUser, function(err, keys) { + expect(err).to.not.exist; + expect(keys).to.exist; + expect(keys.publicKey).to.exist; + expect(keys.privateKey).to.exist; + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + expect(lawnchairDaoStub.read.calledTwice).to.be.true; + done(); + }); + }); + + it('should work if local keys are not already present', function(done) { + lawnchairDaoStub.list.yields(); + pubkeyDaoStub.getByUserId.yields(); + + keychainDao.getUserKeyPair(testUser, function(err, keys) { + expect(err).to.not.exist; + expect(keys).to.not.exist; + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + expect(pubkeyDaoStub.getByUserId.calledOnce).to.be.true; + done(); + }); + }); + + it('should work if local keys are not already present', function(done) { + lawnchairDaoStub.list.yields(); + pubkeyDaoStub.getByUserId.yields(null, { + _id: '12345', + publicKey: 'asdf' + }); + lawnchairDaoStub.read.yields(null, { + _id: '12345', + publicKey: 'asdf', + encryptedKey: 'qwer' + }); + + keychainDao.getUserKeyPair(testUser, function(err, keys) { + expect(err).to.not.exist; + expect(keys).to.exist; + expect(keys.publicKey).to.exist; + expect(keys.privateKey).to.exist; + expect(lawnchairDaoStub.list.calledOnce).to.be.true; + expect(lawnchairDaoStub.read.calledTwice).to.be.true; + done(); + }); + }); + }); + + describe('setDeviceName', function() { + it('should work', function(done) { + lawnchairDaoStub.persist.yields(); + + keychainDao.setDeviceName('iPhone', done); + }); + }); + + describe('getDeviceName', function() { + it('should fail when device name is not set', function(done) { + lawnchairDaoStub.read.withArgs('devicename').yields(); + + keychainDao.getDeviceName(function(err, deviceName) { + expect(err.message).to.equal('Device name not set!'); + expect(deviceName).to.not.exist; + done(); + }); + }); + + it('should fail due to error when reading device name', function(done) { + lawnchairDaoStub.read.withArgs('devicename').yields(42); + + keychainDao.getDeviceName(function(err, deviceName) { + expect(err).to.equal(42); + expect(deviceName).to.not.exist; + done(); + }); + }); + + it('should work', function(done) { + lawnchairDaoStub.read.withArgs('devicename').yields(null, 'iPhone'); + + keychainDao.getDeviceName(function(err, deviceName) { + expect(err).to.not.exist; + expect(deviceName).to.equal('iPhone'); + done(); + }); + }); + }); + + describe('getDeviceSecret', function() { + it('should fail due to error when reading device secret', function(done) { + lawnchairDaoStub.read.withArgs('devicename').yields(null, 'iPhone'); + lawnchairDaoStub.read.withArgs('devicesecret').yields(42); + + keychainDao.getDeviceSecret(function(err, deviceSecret) { + expect(err).to.equal(42); + expect(deviceSecret).to.not.exist; + done(); + }); + }); + + it('should fail due to error when storing device secret', function(done) { + lawnchairDaoStub.read.withArgs('devicename').yields(null, 'iPhone'); + lawnchairDaoStub.read.withArgs('devicesecret').yields(); + lawnchairDaoStub.persist.withArgs('devicesecret').yields(42); + + keychainDao.getDeviceSecret(function(err, deviceSecret) { + expect(err).to.equal(42); + expect(deviceSecret).to.not.exist; + done(); + }); + }); + + it('should work when device secret is not set', function(done) { + lawnchairDaoStub.read.withArgs('devicename').yields(null, 'iPhone'); + lawnchairDaoStub.read.withArgs('devicesecret').yields(); + lawnchairDaoStub.persist.withArgs('devicesecret').yields(); + + keychainDao.getDeviceSecret(function(err, deviceSecret) { + expect(err).to.not.exist; + expect(deviceSecret).to.exist; + done(); + }); + }); + + it('should work when device secret is set', function(done) { + lawnchairDaoStub.read.withArgs('devicename').yields(null, 'iPhone'); + lawnchairDaoStub.read.withArgs('devicesecret').yields(null, 'secret'); + + keychainDao.getDeviceSecret(function(err, deviceSecret) { + expect(err).to.not.exist; + expect(deviceSecret).to.equal('secret'); + done(); + }); + }); + }); + + describe('registerDevice', function() { + var getDeviceNameStub, lookupPublicKeyStub, getDeviceSecretStub; + + beforeEach(function() { + getDeviceNameStub = sinon.stub(keychainDao, 'getDeviceName'); + lookupPublicKeyStub = sinon.stub(keychainDao, 'lookupPublicKey'); + getDeviceSecretStub = sinon.stub(keychainDao, 'getDeviceSecret'); + }); + afterEach(function() { + getDeviceNameStub.restore(); + lookupPublicKeyStub.restore(); + getDeviceSecretStub.restore(); + }); + + it('should fail when reading devicename', function(done) { + getDeviceNameStub.yields(42); + + keychainDao.registerDevice({}, function(err) { + expect(err).to.equal(42); + done(); + }); + }); + + it('should fail in requestDeviceRegistration', function(done) { + getDeviceNameStub.yields(null, 'iPhone'); + + privkeyDaoStub.requestDeviceRegistration.withArgs({ + userId: testUser, + deviceName: 'iPhone' + }).yields(42); + + keychainDao.registerDevice({ + userId: testUser + }, function(err) { + expect(err).to.equal(42); + done(); + }); + }); + + it('should fail due to invalid requestDeviceRegistration return value', function(done) { + getDeviceNameStub.yields(null, 'iPhone'); + + privkeyDaoStub.requestDeviceRegistration.withArgs({ + userId: testUser, + deviceName: 'iPhone' + }).yields(null, {}); + + keychainDao.registerDevice({ + userId: testUser + }, function(err) { + expect(err.message).to.equal('Invalid format for session key!'); + done(); + }); + }); + + it('should fail in lookupPublicKey', function(done) { + getDeviceNameStub.yields(null, 'iPhone'); + + privkeyDaoStub.requestDeviceRegistration.withArgs({ + userId: testUser, + deviceName: 'iPhone' + }).yields(null, { + encryptedRegSessionKey: 'asdf' + }); + + lookupPublicKeyStub.yields(42); + + keychainDao.registerDevice({ + userId: testUser + }, function(err) { + expect(err).to.equal(42); + done(); + }); + }); + + it('should fail when server public key not found', function(done) { + getDeviceNameStub.yields(null, 'iPhone'); + + privkeyDaoStub.requestDeviceRegistration.withArgs({ + userId: testUser, + deviceName: 'iPhone' + }).yields(null, { + encryptedRegSessionKey: 'asdf' + }); + + lookupPublicKeyStub.yields(); + + keychainDao.registerDevice({ + userId: testUser + }, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should fail in decrypt', function(done) { + getDeviceNameStub.yields(null, 'iPhone'); + + privkeyDaoStub.requestDeviceRegistration.withArgs({ + userId: testUser, + deviceName: 'iPhone' + }).yields(null, { + encryptedRegSessionKey: 'asdf' + }); + + lookupPublicKeyStub.yields(null, { + publicKey: 'pubkey' + }); + pgpStub.decrypt.withArgs('asdf', 'pubkey').yields(42); + + keychainDao.registerDevice({ + userId: testUser + }, function(err) { + expect(err).to.equal(42); + done(); + }); + }); + + it('should fail in getDeviceSecret', function(done) { + getDeviceNameStub.yields(null, 'iPhone'); + + privkeyDaoStub.requestDeviceRegistration.withArgs({ + userId: testUser, + deviceName: 'iPhone' + }).yields(null, { + encryptedRegSessionKey: 'asdf' + }); + + lookupPublicKeyStub.yields(null, { + publicKey: 'pubkey' + }); + pgpStub.decrypt.withArgs('asdf', 'pubkey').yields(null, 'decrypted'); + getDeviceSecretStub.yields(42); + + keychainDao.registerDevice({ + userId: testUser + }, function(err) { + expect(err).to.equal(42); + done(); + }); + }); + + it('should fail in encrypt', function(done) { + getDeviceNameStub.yields(null, 'iPhone'); + + privkeyDaoStub.requestDeviceRegistration.withArgs({ + userId: testUser, + deviceName: 'iPhone' + }).yields(null, { + encryptedRegSessionKey: 'asdf' + }); + + lookupPublicKeyStub.yields(null, { + publicKey: 'pubkey' + }); + pgpStub.decrypt.withArgs('asdf', 'pubkey').yields(null, 'decrypted'); + getDeviceSecretStub.yields(null, 'secret'); + cryptoStub.encrypt.withArgs('secret', 'decrypted').yields(42); + + keychainDao.registerDevice({ + userId: testUser + }, function(err) { + expect(err).to.equal(42); + done(); + }); + }); + + it('should work', function(done) { + getDeviceNameStub.yields(null, 'iPhone'); + + privkeyDaoStub.requestDeviceRegistration.withArgs({ + userId: testUser, + deviceName: 'iPhone' + }).yields(null, { + encryptedRegSessionKey: 'asdf' + }); + + lookupPublicKeyStub.yields(null, { + publicKey: 'pubkey' + }); + pgpStub.decrypt.withArgs('asdf', 'pubkey').yields(null, 'decrypted'); + getDeviceSecretStub.yields(null, 'secret'); + cryptoStub.encrypt.withArgs('secret', 'decrypted').yields(null, 'encryptedDeviceSecret'); + privkeyDaoStub.uploadDeviceSecret.yields(); + + keychainDao.registerDevice({ + userId: testUser + }, function(err) { + expect(err).not.exist; + expect(privkeyDaoStub.uploadDeviceSecret.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('_authenticateToPrivateKeyServer', function() { + var lookupPublicKeyStub, getDeviceSecretStub; + + beforeEach(function() { + lookupPublicKeyStub = sinon.stub(keychainDao, 'lookupPublicKey'); + getDeviceSecretStub = sinon.stub(keychainDao, 'getDeviceSecret'); + }); + afterEach(function() { + lookupPublicKeyStub.restore(); + getDeviceSecretStub.restore(); + }); + + it('should fail due to privkeyDao.requestAuthSessionKey', function(done) { + privkeyDaoStub.requestAuthSessionKey.withArgs({ + userId: testUser + }).yields(42); + + keychainDao._authenticateToPrivateKeyServer(testUser, function(err, authSessionKey) { + expect(err).to.equal(42); + expect(authSessionKey).to.not.exist; + done(); + }); + }); + + it('should fail due to privkeyDao.requestAuthSessionKey response', function(done) { + privkeyDaoStub.requestAuthSessionKey.yields(null, {}); + + keychainDao._authenticateToPrivateKeyServer(testUser, function(err, authSessionKey) { + expect(err).to.exist; + expect(authSessionKey).to.not.exist; + done(); + }); + }); + + it('should fail due to lookupPublicKey', function(done) { + privkeyDaoStub.requestAuthSessionKey.yields(null, { + encryptedAuthSessionKey: 'encryptedAuthSessionKey', + encryptedChallenge: 'encryptedChallenge', + sessionId: 'sessionId' + }); + + lookupPublicKeyStub.yields(42); + + keychainDao._authenticateToPrivateKeyServer(testUser, function(err, authSessionKey) { + expect(err).to.exist; + expect(authSessionKey).to.not.exist; + done(); + }); + }); + + it('should fail due to pgp.decrypt', function(done) { + privkeyDaoStub.requestAuthSessionKey.yields(null, { + encryptedAuthSessionKey: 'encryptedAuthSessionKey', + encryptedChallenge: 'encryptedChallenge', + sessionId: 'sessionId' + }); + + lookupPublicKeyStub.yields(null, { + publickKey: 'publicKey' + }); + + pgpStub.decrypt.yields(42); + + keychainDao._authenticateToPrivateKeyServer(testUser, function(err, authSessionKey) { + expect(err).to.exist; + expect(authSessionKey).to.not.exist; + done(); + }); + }); + + it('should fail due to getDeviceSecret', function(done) { + privkeyDaoStub.requestAuthSessionKey.yields(null, { + encryptedAuthSessionKey: 'encryptedAuthSessionKey', + encryptedChallenge: 'encryptedChallenge', + sessionId: 'sessionId' + }); + + lookupPublicKeyStub.yields(null, { + publickKey: 'publicKey' + }); + + pgpStub.decrypt.yields(null, 'decryptedStuff'); + getDeviceSecretStub.yields(42); + + keychainDao._authenticateToPrivateKeyServer(testUser, function(err, authSessionKey) { + expect(err).to.exist; + expect(authSessionKey).to.not.exist; + done(); + }); + }); + + it('should fail due to crypto.encrypt', function(done) { + privkeyDaoStub.requestAuthSessionKey.yields(null, { + encryptedAuthSessionKey: 'encryptedAuthSessionKey', + encryptedChallenge: 'encryptedChallenge', + sessionId: 'sessionId' + }); + + lookupPublicKeyStub.yields(null, { + publickKey: 'publicKey' + }); + + pgpStub.decrypt.yields(null, 'decryptedStuff'); + getDeviceSecretStub.yields(null, 'deviceSecret'); + cryptoStub.encrypt.yields(42); + + keychainDao._authenticateToPrivateKeyServer(testUser, function(err, authSessionKey) { + expect(err).to.exist; + expect(authSessionKey).to.not.exist; + done(); + }); + }); + + it('should fail due to privkeyDao.verifyAuthentication', function(done) { + privkeyDaoStub.requestAuthSessionKey.yields(null, { + encryptedAuthSessionKey: 'encryptedAuthSessionKey', + encryptedChallenge: 'encryptedChallenge', + sessionId: 'sessionId' + }); + + lookupPublicKeyStub.yields(null, { + publickKey: 'publicKey' + }); + + pgpStub.decrypt.yields(null, 'decryptedStuff'); + getDeviceSecretStub.yields(null, 'deviceSecret'); + cryptoStub.encrypt.yields(null, 'encryptedStuff'); + privkeyDaoStub.verifyAuthentication.yields(42); + + keychainDao._authenticateToPrivateKeyServer(testUser, function(err, authSessionKey) { + expect(err).to.exist; + expect(authSessionKey).to.not.exist; + done(); + }); + }); + + it('should fail due to server public key nto found', function(done) { + privkeyDaoStub.requestAuthSessionKey.yields(null, { + encryptedAuthSessionKey: 'encryptedAuthSessionKey', + encryptedChallenge: 'encryptedChallenge', + sessionId: 'sessionId' + }); + + lookupPublicKeyStub.yields(); + + pgpStub.decrypt.yields(null, 'decryptedStuff'); + getDeviceSecretStub.yields(null, 'deviceSecret'); + cryptoStub.encrypt.yields(null, 'encryptedStuff'); + privkeyDaoStub.verifyAuthentication.yields(); + + keychainDao._authenticateToPrivateKeyServer(testUser, function(err, authSessionKey) { + expect(err).to.exist; + expect(authSessionKey).to.not.exist; + done(); + }); + }); + + it('should work', function(done) { + privkeyDaoStub.requestAuthSessionKey.yields(null, { + encryptedAuthSessionKey: 'encryptedAuthSessionKey', + encryptedChallenge: 'encryptedChallenge', + sessionId: 'sessionId' + }); + + lookupPublicKeyStub.yields(null, { + publicKey: 'publicKey' + }); + + pgpStub.decrypt.yields(null, 'decryptedStuff'); + getDeviceSecretStub.yields(null, 'deviceSecret'); + cryptoStub.encrypt.yields(null, 'encryptedStuff'); + privkeyDaoStub.verifyAuthentication.yields(); + + keychainDao._authenticateToPrivateKeyServer(testUser, function(err, authSessionKey) { + expect(err).to.not.exist; + expect(authSessionKey).to.deep.equal({ + sessionKey: 'decryptedStuff', + sessionId: 'sessionId' + }); + done(); + }); + }); + }); + + describe('uploadPrivateKey', function() { + var getUserKeyPairStub, _authenticateToPrivateKeyServerStub; + + beforeEach(function() { + getUserKeyPairStub = sinon.stub(keychainDao, 'getUserKeyPair'); + _authenticateToPrivateKeyServerStub = sinon.stub(keychainDao, '_authenticateToPrivateKeyServer'); + }); + afterEach(function() { + getUserKeyPairStub.restore(); + _authenticateToPrivateKeyServerStub.restore(); + }); + + it('should fail due to missing args', function(done) { + keychainDao.uploadPrivateKey({}, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should fail due to error in derive key', function(done) { + cryptoStub.deriveKey.yields(42); + + keychainDao.uploadPrivateKey({ + code: 'code', + userId: testUser + }, function(err) { + expect(err).to.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + done(); + }); + }); + + it('should fail due to error in getUserKeyPair', function(done) { + cryptoStub.deriveKey.yields(null, 'derivedKey'); + getUserKeyPairStub.yields(42); + + keychainDao.uploadPrivateKey({ + code: 'code', + userId: testUser + }, function(err) { + expect(err).to.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + expect(getUserKeyPairStub.calledOnce).to.be.true; + done(); + }); + }); + + it('should fail due to error in crypto.encrypt', function(done) { + cryptoStub.deriveKey.yields(null, 'derivedKey'); + getUserKeyPairStub.yields(null, { + privateKey: { + _id: 'pgpKeyId', + encryptedKey: 'pgpKey' + } + }); + cryptoStub.encrypt.yields(42); + + keychainDao.uploadPrivateKey({ + code: 'code', + userId: testUser + }, function(err) { + expect(err).to.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + expect(getUserKeyPairStub.calledOnce).to.be.true; + expect(cryptoStub.encrypt.calledOnce).to.be.true; + done(); + }); + }); + + it('should fail due to error in _authenticateToPrivateKeyServer', function(done) { + cryptoStub.deriveKey.yields(null, 'derivedKey'); + getUserKeyPairStub.yields(null, { + privateKey: { + _id: 'pgpKeyId', + encryptedKey: 'pgpKey' + } + }); + cryptoStub.encrypt.yields(null, 'encryptedPgpKey'); + _authenticateToPrivateKeyServerStub.yields(42); + + keychainDao.uploadPrivateKey({ + code: 'code', + userId: testUser + }, function(err) { + expect(err).to.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + expect(getUserKeyPairStub.calledOnce).to.be.true; + expect(cryptoStub.encrypt.calledOnce).to.be.true; + expect(_authenticateToPrivateKeyServerStub.calledOnce).to.be.true; + done(); + }); + }); + + it('should fail due to error in cryptoStub.encrypt', function(done) { + cryptoStub.deriveKey.yields(null, 'derivedKey'); + getUserKeyPairStub.yields(null, { + privateKey: { + _id: 'pgpKeyId', + encryptedKey: 'pgpKey' + } + }); + cryptoStub.encrypt.withArgs('pgpKey').yields(null, 'encryptedPgpKey'); + _authenticateToPrivateKeyServerStub.yields(null, { + sessionId: 'sessionId', + sessionKey: 'sessionKey' + }); + cryptoStub.encrypt.withArgs('encryptedPgpKey').yields(42); + + keychainDao.uploadPrivateKey({ + code: 'code', + userId: testUser + }, function(err) { + expect(err).to.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + expect(getUserKeyPairStub.calledOnce).to.be.true; + expect(cryptoStub.encrypt.calledTwice).to.be.true; + expect(_authenticateToPrivateKeyServerStub.calledOnce).to.be.true; + done(); + }); + }); + + it('should work', function(done) { + cryptoStub.deriveKey.yields(null, 'derivedKey'); + getUserKeyPairStub.yields(null, { + privateKey: { + _id: 'pgpKeyId', + encryptedKey: 'pgpKey' + } + }); + cryptoStub.encrypt.withArgs('pgpKey').yields(null, 'encryptedPgpKey'); + _authenticateToPrivateKeyServerStub.yields(null, { + sessionId: 'sessionId', + sessionKey: 'sessionKey' + }); + cryptoStub.encrypt.withArgs('encryptedPgpKey').yields(null, 'doubleEncryptedPgpKey'); + privkeyDaoStub.upload.yields(); + + keychainDao.uploadPrivateKey({ + code: 'code', + userId: testUser + }, function(err) { + expect(err).to.not.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + expect(getUserKeyPairStub.calledOnce).to.be.true; + expect(cryptoStub.encrypt.calledTwice).to.be.true; + expect(_authenticateToPrivateKeyServerStub.calledOnce).to.be.true; + expect(privkeyDaoStub.upload.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('requestPrivateKeyDownload', function() { + it('should work', function(done) { + var options = { + userId: testUser + }; + + privkeyDaoStub.requestDownload.withArgs(options).yields(); + keychainDao.requestPrivateKeyDownload(options, done); + }); + }); + + describe('downloadPrivateKey', function() { + it('should work', function(done) { + var options = { + recoveryToken: 'token' + }; + + privkeyDaoStub.download.withArgs(options).yields(); + keychainDao.downloadPrivateKey(options, done); + }); + }); + + describe('decryptAndStorePrivateKeyLocally', function() { + var saveLocalPrivateKeyStub, testData; + + beforeEach(function() { + testData = { + _id: 'keyId', + userId: testUser, + encryptedPrivateKey: 'encryptedPrivateKey', + code: 'code', + salt: 'salt', + iv: 'iv' + }; + + saveLocalPrivateKeyStub = sinon.stub(keychainDao, 'saveLocalPrivateKey'); + }); + afterEach(function() { + saveLocalPrivateKeyStub.restore(); + }); + + it('should fail due to invlaid args', function(done) { + keychainDao.decryptAndStorePrivateKeyLocally({}, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should fail due to crypto.deriveKey', function(done) { + cryptoStub.deriveKey.yields(42); + + keychainDao.decryptAndStorePrivateKeyLocally(testData, function(err) { + expect(err).to.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + done(); + }); + }); + + it('should fail due to crypto.decrypt', function(done) { + cryptoStub.deriveKey.yields(null, 'derivedKey'); + cryptoStub.decrypt.yields(42); + + keychainDao.decryptAndStorePrivateKeyLocally(testData, function(err) { + expect(err).to.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + expect(cryptoStub.decrypt.calledOnce).to.be.true; + done(); + }); + }); + + it('should fail due to pgp.getKeyParams', function(done) { + cryptoStub.deriveKey.yields(null, 'derivedKey'); + cryptoStub.decrypt.yields(null, 'privateKeyArmored'); + pgpStub.getKeyParams.throws(new Error()); + + keychainDao.decryptAndStorePrivateKeyLocally(testData, function(err) { + expect(err).to.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + expect(cryptoStub.decrypt.calledOnce).to.be.true; + expect(pgpStub.getKeyParams.calledOnce).to.be.true; + done(); + }); + }); + + it('should fail due to saveLocalPrivateKey', function(done) { + cryptoStub.deriveKey.yields(null, 'derivedKey'); + cryptoStub.decrypt.yields(null, 'privateKeyArmored'); + pgpStub.getKeyParams.returns(testData); + saveLocalPrivateKeyStub.yields(42); + + keychainDao.decryptAndStorePrivateKeyLocally(testData, function(err) { + expect(err).to.exist; + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + expect(cryptoStub.decrypt.calledOnce).to.be.true; + expect(pgpStub.getKeyParams.calledOnce).to.be.true; + expect(saveLocalPrivateKeyStub.calledOnce).to.be.true; + done(); + }); + }); + + it('should work', function(done) { + cryptoStub.deriveKey.yields(null, 'derivedKey'); + cryptoStub.decrypt.yields(null, 'privateKeyArmored'); + pgpStub.getKeyParams.returns(testData); + saveLocalPrivateKeyStub.yields(); + + keychainDao.decryptAndStorePrivateKeyLocally(testData, function(err, keyObject) { + expect(err).to.not.exist; + expect(keyObject).to.deep.equal({ + _id: 'keyId', + userId: testUser, + encryptedKey: 'privateKeyArmored' + }); + expect(cryptoStub.deriveKey.calledOnce).to.be.true; + expect(cryptoStub.decrypt.calledOnce).to.be.true; + expect(pgpStub.getKeyParams.calledOnce).to.be.true; + expect(saveLocalPrivateKeyStub.calledOnce).to.be.true; + + done(); + }); + }); + }); + + describe('put user keypair', function() { + it('should fail', function(done) { + var keypair = { + publicKey: { + _id: '12345', + userId: testUser, + publicKey: 'asdf' + }, + privateKey: { + _id: '12345', + encryptedKey: 'qwer' + } + }; + + keychainDao.putUserKeyPair(keypair, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should work', function(done) { + var keypair = { + publicKey: { + _id: '12345', + userId: testUser, + publicKey: 'asdf' + }, + privateKey: { + _id: '12345', + userId: testUser, + encryptedKey: 'qwer' + } + }; + + lawnchairDaoStub.persist.yields(); + pubkeyDaoStub.put.yields(); + + keychainDao.putUserKeyPair(keypair, function(err) { + expect(err).to.not.exist; + expect(lawnchairDaoStub.persist.calledTwice).to.be.true; + expect(pubkeyDaoStub.put.calledOnce).to.be.true; + done(); + }); + }); + }); + + }); }); \ No newline at end of file diff --git a/test/new-unit/lawnchair-dao-test.js b/test/unit/lawnchair-dao-test.js similarity index 100% rename from test/new-unit/lawnchair-dao-test.js rename to test/unit/lawnchair-dao-test.js diff --git a/test/new-unit/login-ctrl-test.js b/test/unit/login-ctrl-test.js similarity index 77% rename from test/new-unit/login-ctrl-test.js rename to test/unit/login-ctrl-test.js index 9ca206b..52176f6 100644 --- a/test/new-unit/login-ctrl-test.js +++ b/test/unit/login-ctrl-test.js @@ -7,10 +7,13 @@ define(function(require) { LoginCtrl = require('js/controller/login'), EmailDAO = require('js/dao/email-dao'), Auth = require('js/bo/auth'), - appController = require('js/app-controller'); + appController = require('js/app-controller'), + KeychainDAO = require('js/dao/keychain-dao'); describe('Login Controller unit test', function() { - var scope, location, ctrl, origEmailDao, emailDaoMock, + var scope, location, ctrl, + origEmailDao, emailDaoMock, + origKeychain, keychainMock, emailAddress = 'fred@foo.com', startAppStub, checkForUpdateStub, @@ -21,14 +24,16 @@ define(function(require) { var hasChrome, hasIdentity; beforeEach(function() { - hasChrome = !! window.chrome; - hasIdentity = !! window.chrome.identity; + hasChrome = !!window.chrome; + hasIdentity = !!window.chrome.identity; window.chrome = window.chrome || {}; window.chrome.identity = window.chrome.identity || {}; // remember original module to restore later, then replace it origEmailDao = appController._emailDao; + origKeychain = appController._keychain; appController._emailDao = emailDaoMock = sinon.createStubInstance(EmailDAO); + appController._keychain = keychainMock = sinon.createStubInstance(KeychainDAO); appController._auth = authStub = sinon.createStubInstance(Auth); startAppStub = sinon.stub(appController, 'start'); @@ -48,6 +53,7 @@ define(function(require) { // restore the app controller module appController._emailDao = origEmailDao; + appController._keychain = origKeychain; appController.start.restore && appController.start.restore(); appController.checkForUpdate.restore && appController.checkForUpdate.restore(); appController.init.restore && appController.init.restore(); @@ -128,12 +134,42 @@ define(function(require) { }); }); + it('should forward to privatekey download login', function(done) { + startAppStub.yields(); + authStub.getEmailAddress.yields(null, emailAddress); + initStub.yields(null, { + publicKey: 'b' + }); + keychainMock.requestPrivateKeyDownload.yields(null, {}); + + angular.module('logintest', []); + mocks.module('logintest'); + mocks.inject(function($controller, $rootScope, $location) { + location = $location; + sinon.stub(location, 'path', function(path) { + expect(path).to.equal('/login-privatekey-download'); + expect(startAppStub.calledOnce).to.be.true; + expect(checkForUpdateStub.calledOnce).to.be.true; + expect(authStub.getEmailAddress.calledOnce).to.be.true; + expect(keychainMock.requestPrivateKeyDownload.calledOnce).to.be.true; + done(); + }); + scope = $rootScope.$new(); + scope.state = {}; + ctrl = $controller(LoginCtrl, { + $location: location, + $scope: scope + }); + }); + }); + it('should forward to new device login', function(done) { startAppStub.yields(); authStub.getEmailAddress.yields(null, emailAddress); initStub.yields(null, { publicKey: 'b' }); + keychainMock.requestPrivateKeyDownload.yields(); angular.module('logintest', []); mocks.module('logintest'); @@ -144,6 +180,7 @@ define(function(require) { expect(startAppStub.calledOnce).to.be.true; expect(checkForUpdateStub.calledOnce).to.be.true; expect(authStub.getEmailAddress.calledOnce).to.be.true; + expect(keychainMock.requestPrivateKeyDownload.calledOnce).to.be.true; done(); }); scope = $rootScope.$new(); diff --git a/test/new-unit/login-existing-ctrl-test.js b/test/unit/login-existing-ctrl-test.js similarity index 100% rename from test/new-unit/login-existing-ctrl-test.js rename to test/unit/login-existing-ctrl-test.js diff --git a/test/new-unit/login-initial-ctrl-test.js b/test/unit/login-initial-ctrl-test.js similarity index 100% rename from test/new-unit/login-initial-ctrl-test.js rename to test/unit/login-initial-ctrl-test.js diff --git a/test/new-unit/login-new-device-ctrl-test.js b/test/unit/login-new-device-ctrl-test.js similarity index 100% rename from test/new-unit/login-new-device-ctrl-test.js rename to test/unit/login-new-device-ctrl-test.js diff --git a/test/unit/login-privatekey-download-ctrl-test.js b/test/unit/login-privatekey-download-ctrl-test.js new file mode 100644 index 0000000..bb9c32a --- /dev/null +++ b/test/unit/login-privatekey-download-ctrl-test.js @@ -0,0 +1,235 @@ +define(function(require) { + 'use strict'; + + var expect = chai.expect, + angular = require('angular'), + mocks = require('angularMocks'), + LoginPrivateKeyDownloadCtrl = require('js/controller/login-privatekey-download'), + EmailDAO = require('js/dao/email-dao'), + appController = require('js/app-controller'), + KeychainDAO = require('js/dao/keychain-dao'); + + describe('Login Private Key Download Controller unit test', function() { + var scope, location, ctrl, + origEmailDao, emailDaoMock, + origKeychain, keychainMock, + emailAddress = 'fred@foo.com'; + + beforeEach(function(done) { + // remember original module to restore later, then replace it + origEmailDao = appController._emailDao; + origKeychain = appController._keychain; + appController._emailDao = emailDaoMock = sinon.createStubInstance(EmailDAO); + appController._keychain = keychainMock = sinon.createStubInstance(KeychainDAO); + + emailDaoMock._account = { + emailAddress: emailAddress + }; + + angular.module('login-privatekey-download-test', []); + mocks.module('login-privatekey-download-test'); + mocks.inject(function($controller, $rootScope) { + scope = $rootScope.$new(); + scope.state = {}; + ctrl = $controller(LoginPrivateKeyDownloadCtrl, { + $location: location, + $scope: scope + }); + done(); + }); + }); + + afterEach(function() { + // restore the app controller module + appController._emailDao = origEmailDao; + appController._keychain = origKeychain; + }); + + describe('initialization', function() { + it('should work', function() { + expect(scope.step).to.equal(1); + }); + }); + + describe('verifyRecoveryToken', function() { + var testKeypair = { + publicKey: { + _id: 'id' + } + }; + + it('should fail for empty recovery token', function(done) { + scope.onError = function(err) { + expect(err).to.exist; + done(); + }; + + scope.recoveryToken = undefined; + scope.verifyRecoveryToken(); + }); + + it('should fail in keychain.getUserKeyPair', function(done) { + keychainMock.getUserKeyPair.yields(42); + + scope.onError = function(err) { + expect(err).to.exist; + expect(keychainMock.getUserKeyPair.calledOnce).to.be.true; + done(); + }; + + scope.recoveryToken = 'token'; + scope.verifyRecoveryToken(); + }); + + it('should fail in keychain.downloadPrivateKey', function(done) { + keychainMock.getUserKeyPair.yields(null, testKeypair); + keychainMock.downloadPrivateKey.yields(42); + + scope.onError = function(err) { + expect(err).to.exist; + expect(keychainMock.getUserKeyPair.calledOnce).to.be.true; + expect(keychainMock.downloadPrivateKey.calledOnce).to.be.true; + done(); + }; + + scope.recoveryToken = 'token'; + scope.verifyRecoveryToken(); + }); + + it('should work', function(done) { + keychainMock.getUserKeyPair.yields(null, testKeypair); + keychainMock.downloadPrivateKey.yields(null, 'encryptedPrivateKey'); + + scope.recoveryToken = 'token'; + scope.verifyRecoveryToken(function() { + expect(scope.encryptedPrivateKey).to.equal('encryptedPrivateKey'); + done(); + }); + }); + }); + + describe('decryptAndStorePrivateKeyLocally', function() { + beforeEach(function() { + scope.code0 = '0'; + scope.code1 = '1'; + scope.code2 = '2'; + scope.code3 = '3'; + scope.code4 = '4'; + scope.code5 = '5'; + + scope.encryptedPrivateKey = { + encryptedPrivateKey: 'encryptedPrivateKey' + }; + scope.cachedKeypair = { + publicKey: { + _id: 'keyId' + } + }; + }); + + it('should fail on empty code', function(done) { + scope.code0 = ''; + scope.code1 = ''; + scope.code2 = ''; + scope.code3 = ''; + scope.code4 = ''; + scope.code5 = ''; + + scope.onError = function(err) { + expect(err).to.exist; + done(); + }; + + scope.decryptAndStorePrivateKeyLocally(); + }); + + it('should fail on decryptAndStorePrivateKeyLocally', function(done) { + keychainMock.decryptAndStorePrivateKeyLocally.yields(42); + + scope.onError = function(err) { + expect(err).to.exist; + expect(keychainMock.decryptAndStorePrivateKeyLocally.calledOnce).to.be.true; + done(); + }; + + scope.decryptAndStorePrivateKeyLocally(); + }); + + it('should goto /login-existing on emailDao.unlock fail', function(done) { + keychainMock.decryptAndStorePrivateKeyLocally.yields(null, { + encryptedKey: 'keyArmored' + }); + emailDaoMock.unlock.yields(42); + + scope.goTo = function(location) { + expect(location).to.equal('/login-existing'); + expect(keychainMock.decryptAndStorePrivateKeyLocally.calledOnce).to.be.true; + expect(emailDaoMock.unlock.calledOnce).to.be.true; + done(); + }; + + scope.decryptAndStorePrivateKeyLocally(); + }); + + it('should goto /desktop on emailDao.unlock success', function(done) { + keychainMock.decryptAndStorePrivateKeyLocally.yields(null, { + encryptedKey: 'keyArmored' + }); + emailDaoMock.unlock.yields(); + + scope.goTo = function(location) { + expect(location).to.equal('/desktop'); + expect(keychainMock.decryptAndStorePrivateKeyLocally.calledOnce).to.be.true; + expect(emailDaoMock.unlock.calledOnce).to.be.true; + done(); + }; + + scope.decryptAndStorePrivateKeyLocally(); + }); + }); + + describe('goForward', function() { + it('should work in step 1', function() { + var verifyRecoveryTokenStub = sinon.stub(scope, 'verifyRecoveryToken'); + verifyRecoveryTokenStub.yields(); + scope.step = 1; + + scope.goForward(); + + expect(verifyRecoveryTokenStub.calledOnce).to.be.true; + expect(scope.step).to.equal(2); + verifyRecoveryTokenStub.restore(); + }); + it('should work in step 2', function() { + var decryptAndStorePrivateKeyLocallyStub = sinon.stub(scope, 'decryptAndStorePrivateKeyLocally'); + decryptAndStorePrivateKeyLocallyStub.returns(); + scope.step = 2; + + scope.goForward(); + + expect(decryptAndStorePrivateKeyLocallyStub.calledOnce).to.be.true; + decryptAndStorePrivateKeyLocallyStub.restore(); + }); + }); + + describe('goTo', function() { + it('should work', function(done) { + mocks.inject(function($controller, $rootScope, $location) { + location = $location; + sinon.stub(location, 'path', function(path) { + expect(path).to.equal('/desktop'); + done(); + }); + scope = $rootScope.$new(); + scope.state = {}; + ctrl = $controller(LoginPrivateKeyDownloadCtrl, { + $location: location, + $scope: scope + }); + }); + + scope.goTo('/desktop'); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/new-unit/mail-list-ctrl-test.js b/test/unit/mail-list-ctrl-test.js similarity index 100% rename from test/new-unit/mail-list-ctrl-test.js rename to test/unit/mail-list-ctrl-test.js diff --git a/test/unit/main.js b/test/unit/main.js index f6da06d..44b541e 100644 --- a/test/unit/main.js +++ b/test/unit/main.js @@ -1,16 +1,22 @@ 'use strict'; require(['../../src/require-config'], function() { - require.config({ - baseUrl: '../../src/lib' + baseUrl: '../../src/lib', + paths: { + angularMocks: '../../test/lib/angular-mocks' + }, + shim: { + angularMocks: { + exports: 'angular.mock', + deps: ['angular'] + } + } }); - // Start the main app logic. - require(['js/app-config', 'cordova'], function(app) { - // clear session storage of failed tests, so async order is correct after fail & refresh - window.sessionStorage.clear(); + // Start the main app logic. + require(['js/app-config'], function(app) { app.config.workerPath = '../../src/js'; startTests(); @@ -18,17 +24,43 @@ require(['../../src/require-config'], function() { }); function startTests() { + mocha.setup('bdd'); + require( [ - 'test/unit/forge-test', - 'test/unit/aes-test', - 'test/unit/rsa-test', - 'test/unit/keychain-dao-test', + 'test/unit/oauth-test', + 'test/unit/auth-test', + 'test/unit/email-dao-test', + 'test/unit/app-controller-test', + 'test/unit/pgp-test', 'test/unit/crypto-test', - 'test/unit/devicestorage-dao-test' + 'test/unit/rest-dao-test', + 'test/unit/publickey-dao-test', + 'test/unit/privatekey-dao-test', + 'test/unit/lawnchair-dao-test', + 'test/unit/keychain-dao-test', + 'test/unit/devicestorage-dao-test', + 'test/unit/dialog-ctrl-test', + 'test/unit/add-account-ctrl-test', + 'test/unit/account-ctrl-test', + 'test/unit/set-passphrase-ctrl-test', + 'test/unit/contacts-ctrl-test', + 'test/unit/login-existing-ctrl-test', + 'test/unit/login-initial-ctrl-test', + 'test/unit/login-new-device-ctrl-test', + 'test/unit/login-privatekey-download-ctrl-test', + 'test/unit/privatekey-upload-ctrl-test', + 'test/unit/login-ctrl-test', + 'test/unit/read-ctrl-test', + 'test/unit/navigation-ctrl-test', + 'test/unit/mail-list-ctrl-test', + 'test/unit/write-ctrl-test', + 'test/unit/outbox-bo-test', + 'test/unit/invitation-dao-test', + 'test/unit/update-handler-test' ], function() { //Tests loaded, run tests - QUnit.start(); + mocha.run(); } ); } \ No newline at end of file diff --git a/test/new-unit/navigation-ctrl-test.js b/test/unit/navigation-ctrl-test.js similarity index 100% rename from test/new-unit/navigation-ctrl-test.js rename to test/unit/navigation-ctrl-test.js diff --git a/test/new-unit/oauth-test.js b/test/unit/oauth-test.js similarity index 100% rename from test/new-unit/oauth-test.js rename to test/unit/oauth-test.js diff --git a/test/new-unit/outbox-bo-test.js b/test/unit/outbox-bo-test.js similarity index 100% rename from test/new-unit/outbox-bo-test.js rename to test/unit/outbox-bo-test.js diff --git a/test/new-unit/pgp-test.js b/test/unit/pgp-test.js similarity index 98% rename from test/new-unit/pgp-test.js rename to test/unit/pgp-test.js index 57aadf1..b0c64ae 100644 --- a/test/new-unit/pgp-test.js +++ b/test/unit/pgp-test.js @@ -13,7 +13,7 @@ define(function(require) { keySize = 512, keyId = 'F6F60E9B42CDFF4C', pubkey = '-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n' + - 'Version: OpenPGP.js v0.5.1\r\n' + + 'Version: OpenPGP.js v0.6.0\r\n' + 'Comment: http://openpgpjs.org\r\n' + '\r\n' + 'xk0EUlhMvAEB/2MZtCUOAYvyLFjDp3OBMGn3Ev8FwjzyPbIF0JUw+L7y2XR5\r\n' + @@ -24,7 +24,7 @@ define(function(require) { '=6XMW\r\n' + '-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n', privkey = '-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n' + - 'Version: OpenPGP.js v0.5.1\r\n' + + 'Version: OpenPGP.js v0.6.0\r\n' + 'Comment: http://openpgpjs.org\r\n' + '\r\n' + 'xcBeBFJYTLwBAf9jGbQlDgGL8ixYw6dzgTBp9xL/BcI88j2yBdCVMPi+8tl0\r\n' + @@ -92,7 +92,7 @@ define(function(require) { publicKeyArmored: pubkey }, function(err) { expect(err).to.exist; - expect(err.errMsg).to.equal('Incorrect passphrase!'); + expect(err.message).to.equal('Incorrect passphrase!'); pgp.exportKeys(function(err, keys) { expect(err).to.exist; diff --git a/test/unit/privatekey-dao-test.js b/test/unit/privatekey-dao-test.js new file mode 100644 index 0000000..8234a03 --- /dev/null +++ b/test/unit/privatekey-dao-test.js @@ -0,0 +1,201 @@ +define(function(require) { + 'use strict'; + + var RestDAO = require('js/dao/rest-dao'), + PrivateKeyDAO = require('js/dao/privatekey-dao'), + expect = chai.expect; + + describe('Private Key DAO unit tests', function() { + + var privkeyDao, restDaoStub, + emailAddress = 'test@example.com', + deviceName = 'iPhone Work'; + + beforeEach(function() { + restDaoStub = sinon.createStubInstance(RestDAO); + privkeyDao = new PrivateKeyDAO(restDaoStub); + }); + + afterEach(function() {}); + + describe('requestDeviceRegistration', function() { + it('should fail due to invalid args', function(done) { + privkeyDao.requestDeviceRegistration({}, function(err, sessionKey) { + expect(err).to.exist; + expect(sessionKey).to.not.exist; + done(); + }); + }); + + it('should work', function(done) { + restDaoStub.post.yields(null, { + encryptedRegSessionKey: 'asdf' + }); + + privkeyDao.requestDeviceRegistration({ + userId: emailAddress, + deviceName: deviceName + }, function(err, sessionKey) { + expect(err).to.not.exist; + expect(sessionKey).to.exist; + done(); + }); + }); + }); + + describe('uploadDeviceSecret', function() { + it('should fail due to invalid args', function(done) { + privkeyDao.uploadDeviceSecret({}, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should work', function(done) { + restDaoStub.put.yields(); + + privkeyDao.uploadDeviceSecret({ + userId: emailAddress, + deviceName: deviceName, + encryptedDeviceSecret: 'asdf', + iv: 'iv' + }, function(err) { + expect(err).to.not.exist; + done(); + }); + }); + }); + + describe('requestAuthSessionKey', function() { + it('should fail due to invalid args', function(done) { + privkeyDao.requestAuthSessionKey({}, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should work', function(done) { + restDaoStub.post.withArgs(undefined, '/auth/user/' + emailAddress).yields(); + + privkeyDao.requestAuthSessionKey({ + userId: emailAddress + }, function(err) { + expect(err).to.not.exist; + done(); + }); + }); + }); + + describe('verifyAuthentication', function() { + it('should fail due to invalid args', function(done) { + privkeyDao.verifyAuthentication({}, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should work', function(done) { + var sessionId = '1'; + + var options = { + userId: emailAddress, + sessionId: sessionId, + encryptedChallenge: 'asdf', + encryptedDeviceSecret: 'qwer', + iv: ' iv' + }; + + restDaoStub.put.withArgs(options, '/auth/user/' + emailAddress + '/session/' + sessionId).yields(); + + privkeyDao.verifyAuthentication(options, function(err) { + expect(err).to.not.exist; + done(); + }); + }); + }); + + describe('upload', function() { + it('should fail due to invalid args', function(done) { + privkeyDao.upload({}, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should work', function(done) { + var options = { + _id: '12345', + userId: emailAddress, + encryptedPrivateKey: 'asdf', + sessionId: '1', + salt: 'salt', + iv: 'iv' + }; + + restDaoStub.post.withArgs(options, '/privatekey/user/' + emailAddress + '/session/' + options.sessionId).yields(); + + privkeyDao.upload(options, function(err) { + expect(err).to.not.exist; + done(); + }); + }); + }); + + describe('requestDownload', function() { + it('should fail due to invalid args', function(done) { + privkeyDao.requestDownload({}, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should work', function(done) { + var key = { + _id: '12345' + }; + + restDaoStub.get.withArgs({ + uri: '/privatekey/user/' + emailAddress + '/key/' + key._id + }).yields(); + + privkeyDao.requestDownload({ + userId: emailAddress, + keyId: key._id + }, function(err) { + expect(err).to.not.exist; + done(); + }); + }); + }); + + describe('download', function() { + it('should fail due to invalid args', function(done) { + privkeyDao.download({}, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should work', function(done) { + var key = { + _id: '12345' + }; + + restDaoStub.get.withArgs({ + uri: '/privatekey/user/' + emailAddress + '/key/' + key._id + '/recovery/token' + }).yields(); + + privkeyDao.download({ + userId: emailAddress, + keyId: key._id, + recoveryToken: 'token' + }, function(err) { + expect(err).to.not.exist; + done(); + }); + }); + }); + + }); + +}); \ No newline at end of file diff --git a/test/unit/privatekey-upload-ctrl-test.js b/test/unit/privatekey-upload-ctrl-test.js new file mode 100644 index 0000000..5ee8328 --- /dev/null +++ b/test/unit/privatekey-upload-ctrl-test.js @@ -0,0 +1,260 @@ +define(function(require) { + 'use strict'; + + var expect = chai.expect, + angular = require('angular'), + mocks = require('angularMocks'), + PrivateKeyUploadCtrl = require('js/controller/privatekey-upload'), + appController = require('js/app-controller'), + KeychainDAO = require('js/dao/keychain-dao'), + PGP = require('js/crypto/pgp'); + + describe('Private Key Upload Controller unit test', function() { + var scope, location, ctrl, + origEmailDao, emailDaoMock, + origKeychain, keychainMock, + pgpStub, + emailAddress = 'fred@foo.com'; + + beforeEach(function(done) { + // remember original module to restore later, then replace it + origEmailDao = appController._emailDao; + appController._emailDao = emailDaoMock = { + _account: { + emailAddress: emailAddress + } + }; + origKeychain = appController._keychain; + appController._keychain = keychainMock = sinon.createStubInstance(KeychainDAO); + keychainMock._pgp = pgpStub = sinon.createStubInstance(PGP); + + angular.module('login-privatekey-download-test', []); + mocks.module('login-privatekey-download-test'); + mocks.inject(function($controller, $rootScope) { + scope = $rootScope.$new(); + scope.state = {}; + ctrl = $controller(PrivateKeyUploadCtrl, { + $location: location, + $scope: scope + }); + done(); + }); + }); + + afterEach(function() { + // restore the app controller module + appController._keychain = origKeychain; + appController._emailDao = origEmailDao; + }); + + describe('checkServerForKey', function() { + var keyParams = { + userId: emailAddress, + _id: 'keyId' + }; + + it('should fail', function(done) { + pgpStub.getKeyParams.returns(keyParams); + keychainMock.requestPrivateKeyDownload.yields(42); + + scope.onError = function(err) { + expect(err).to.exist; + expect(keychainMock.requestPrivateKeyDownload.calledOnce).to.be.true; + done(); + }; + + scope.checkServerForKey(); + }); + + it('should return true', function(done) { + pgpStub.getKeyParams.returns(keyParams); + keychainMock.requestPrivateKeyDownload.yields(null, true); + + scope.checkServerForKey(function(privateKeySynced) { + expect(privateKeySynced).to.be.true; + done(); + }); + }); + + it('should return undefined', function(done) { + pgpStub.getKeyParams.returns(keyParams); + keychainMock.requestPrivateKeyDownload.yields(null, false); + + scope.checkServerForKey(function(privateKeySynced) { + expect(privateKeySynced).to.be.undefined; + done(); + }); + }); + }); + + describe('displayUploadUi', function() { + it('should work', function() { + var generateCodeStub = sinon.stub(scope, 'generateCode'); + generateCodeStub.returns('asdf'); + + scope.displayUploadUi(); + expect(scope.step).to.equal(1); + expect(scope.code).to.equal('asdf'); + + generateCodeStub.restore(); + }); + }); + + describe('generateCode', function() { + it('should work', function() { + expect(scope.generateCode().length).to.equal(24); + }); + }); + + describe('verifyCode', function() { + it('should fail for wrong code', function() { + scope.code0 = 'b'; + scope.code1 = 'b'; + scope.code2 = 'b'; + scope.code3 = 'b'; + scope.code4 = 'b'; + scope.code5 = 'b'; + scope.code = 'aaaaaa'; + + scope.onError = function() {}; + expect(scope.verifyCode()).to.be.false; + }); + + it('should work', function() { + scope.code0 = 'a'; + scope.code1 = 'a'; + scope.code2 = 'a'; + scope.code3 = 'a'; + scope.code4 = 'a'; + scope.code5 = 'a'; + scope.code = 'aaaaaa'; + + scope.onError = function() {}; + expect(scope.verifyCode()).to.be.false; + }); + }); + + describe('setDeviceName', function() { + it('should work', function(done) { + keychainMock.setDeviceName.yields(); + scope.setDeviceName(done); + }); + }); + + describe('encryptAndUploadKey', function() { + it('should fail due to keychain.registerDevice', function(done) { + keychainMock.registerDevice.yields(42); + + scope.onError = function(err) { + expect(err).to.exist; + expect(keychainMock.registerDevice.calledOnce).to.be.true; + done(); + }; + + scope.encryptAndUploadKey(); + }); + + it('should work', function(done) { + keychainMock.registerDevice.yields(); + keychainMock.uploadPrivateKey.yields(); + + scope.encryptAndUploadKey(function(err) { + expect(err).to.not.exist; + expect(keychainMock.registerDevice.calledOnce).to.be.true; + expect(keychainMock.uploadPrivateKey.calledOnce).to.be.true; + done(); + }); + }); + }); + + describe('goBack', function() { + it('should work', function() { + scope.step = 2; + scope.goBack(); + expect(scope.step).to.equal(1); + }); + + it('should not work for < 2', function() { + scope.step = 1; + scope.goBack(); + expect(scope.step).to.equal(1); + }); + }); + + describe('goForward', function() { + var verifyCodeStub, setDeviceNameStub, encryptAndUploadKeyStub; + beforeEach(function() { + verifyCodeStub = sinon.stub(scope, 'verifyCode'); + setDeviceNameStub = sinon.stub(scope, 'setDeviceName'); + encryptAndUploadKeyStub = sinon.stub(scope, 'encryptAndUploadKey'); + }); + afterEach(function() { + verifyCodeStub.restore(); + setDeviceNameStub.restore(); + encryptAndUploadKeyStub.restore(); + }); + + it('should work for < 2', function() { + scope.step = 1; + scope.goForward(); + expect(scope.step).to.equal(2); + }); + + it('should work for 2', function() { + verifyCodeStub.returns(true); + scope.step = 2; + scope.goForward(); + expect(scope.step).to.equal(3); + }); + + it('should not work for 2 when code invalid', function() { + verifyCodeStub.returns(false); + scope.step = 2; + scope.goForward(); + expect(scope.step).to.equal(2); + }); + + it('should fail for 3 due to error in setDeviceName', function(done) { + scope.step = 3; + setDeviceNameStub.yields(42); + + scope.onError = function(err) { + expect(err).to.exist; + expect(scope.step).to.equal(3); + done(); + }; + + scope.goForward(); + }); + + it('should fail for 3 due to error in encryptAndUploadKey', function(done) { + scope.step = 3; + setDeviceNameStub.yields(); + encryptAndUploadKeyStub.yields(42); + + scope.onError = function(err) { + expect(err).to.exist; + expect(scope.step).to.equal(4); + done(); + }; + + scope.goForward(); + }); + + it('should work for 3', function(done) { + scope.step = 3; + setDeviceNameStub.yields(); + encryptAndUploadKeyStub.yields(); + + scope.onError = function(err) { + expect(err.title).to.equal('Success'); + expect(scope.step).to.equal(4); + done(); + }; + + scope.goForward(); + }); + }); + + }); +}); \ No newline at end of file diff --git a/test/new-unit/publickey-dao-test.js b/test/unit/publickey-dao-test.js similarity index 100% rename from test/new-unit/publickey-dao-test.js rename to test/unit/publickey-dao-test.js diff --git a/test/new-unit/read-ctrl-test.js b/test/unit/read-ctrl-test.js similarity index 100% rename from test/new-unit/read-ctrl-test.js rename to test/unit/read-ctrl-test.js diff --git a/test/new-unit/rest-dao-test.js b/test/unit/rest-dao-test.js similarity index 88% rename from test/new-unit/rest-dao-test.js rename to test/unit/rest-dao-test.js index 57859dc..0bb2e06 100644 --- a/test/new-unit/rest-dao-test.js +++ b/test/unit/rest-dao-test.js @@ -145,6 +145,31 @@ define(function(require) { }); }); + describe('post', function() { + it('should fail', function() { + restDao.post('/asdf', {}, function(err) { + expect(err).to.exist; + expect(err.code).to.equal(500); + }); + + expect(requests.length).to.equal(1); + requests[0].respond(500, { + "Content-Type": "text/plain" + }, 'Internal error'); + }); + + it('should work', function() { + restDao.post('/asdf', {}, function(err, res, status) { + expect(err).to.not.exist; + expect(res).to.equal(''); + expect(status).to.equal(201); + }); + + expect(requests.length).to.equal(1); + requests[0].respond(201); + }); + }); + describe('put', function() { it('should fail', function() { restDao.put('/asdf', {}, function(err) { diff --git a/test/unit/rsa-test.js b/test/unit/rsa-test.js deleted file mode 100644 index 8f0fad5..0000000 --- a/test/unit/rsa-test.js +++ /dev/null @@ -1,53 +0,0 @@ -define(['cryptoLib/rsa'], function(rsa) { - 'use strict'; - - module("RSA Crypto"); - - var rsaTest = { - keySize: 1024, - testMessage: '06a9214036b8a15b512e03d534120006' - }; - - asyncTest("Generate keypair", 1, function() { - rsa.generateKeypair(rsaTest.keySize, function(err) { - ok(!err); - - start(); - }); - }); - - test("Export keys", 2, function() { - rsaTest.keypair = rsa.exportKeys(); - - ok(rsaTest.keypair.pubkeyPem.indexOf('-----BEGIN PUBLIC KEY-----') === 0, rsaTest.keypair.pubkeyPem); - ok(rsaTest.keypair.privkeyPem.indexOf('-----BEGIN RSA PRIVATE KEY-----') === 0, rsaTest.keypair.privkeyPem); - }); - - test("Init", 2, function() { - rsa.init(rsaTest.keypair.pubkeyPem, rsaTest.keypair.privkeyPem); - var exported = rsa.exportKeys(); - - ok(exported.pubkeyPem.indexOf('-----BEGIN PUBLIC KEY-----') === 0); - ok(exported.privkeyPem.indexOf('-----BEGIN RSA PRIVATE KEY-----') === 0); - }); - - test("Encrypt", 1, function() { - rsaTest.ct = rsa.encrypt(rsaTest.testMessage); - ok(rsaTest.ct); - }); - - test("Decrypt", 1, function() { - var pt = rsa.decrypt(rsaTest.ct); - equal(pt, rsaTest.testMessage); - }); - - test("Sign", 1, function() { - rsaTest.sig = rsa.sign([btoa('iv'), btoa(rsaTest.testMessage)]); - ok(rsaTest.sig); - }); - - test("Verify", 1, function() { - var res = rsa.verify([btoa('iv'), btoa(rsaTest.testMessage)], rsaTest.sig); - ok(res); - }); -}); \ No newline at end of file diff --git a/test/new-unit/set-passphrase-ctrl-test.js b/test/unit/set-passphrase-ctrl-test.js similarity index 97% rename from test/new-unit/set-passphrase-ctrl-test.js rename to test/unit/set-passphrase-ctrl-test.js index 8709556..5c4062b 100644 --- a/test/new-unit/set-passphrase-ctrl-test.js +++ b/test/unit/set-passphrase-ctrl-test.js @@ -16,7 +16,7 @@ define(function(require) { emailAddress, keySize, cryptoMock, keychainMock; beforeEach(function() { - appController._crypto = cryptoMock = sinon.createStubInstance(PGP); + appController._pgp = cryptoMock = sinon.createStubInstance(PGP); appController._keychain = keychainMock = sinon.createStubInstance(KeychainDAO); dummyFingerprint = '3A2D39B4E1404190B8B949DE7D7E99036E712926'; diff --git a/test/new-unit/update-handler-test.js b/test/unit/update-handler-test.js similarity index 100% rename from test/new-unit/update-handler-test.js rename to test/unit/update-handler-test.js diff --git a/test/new-unit/write-ctrl-test.js b/test/unit/write-ctrl-test.js similarity index 100% rename from test/new-unit/write-ctrl-test.js rename to test/unit/write-ctrl-test.js