commit
f0808c6e0c
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,5 +5,7 @@ npm*
|
|||
src/compression/
|
||||
test/lib/
|
||||
dist/
|
||||
dist/*.tgz
|
||||
dist/*_debug.js
|
||||
openpgp.store/
|
||||
doc/
|
||||
|
|
32
Gruntfile.js
32
Gruntfile.js
|
@ -1,5 +1,7 @@
|
|||
module.exports = function(grunt) {
|
||||
|
||||
var version = grunt.option('release');
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
|
@ -150,6 +152,34 @@ module.exports = function(grunt) {
|
|||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||
|
||||
grunt.registerTask('set_version', function() {
|
||||
if (!version) {
|
||||
throw new Error('You must specify the version: "--release=1.0.0"');
|
||||
}
|
||||
|
||||
patchFile({
|
||||
fileName: 'package.json',
|
||||
version: version
|
||||
});
|
||||
|
||||
patchFile({
|
||||
fileName: 'bower.json',
|
||||
version: version
|
||||
});
|
||||
});
|
||||
|
||||
function patchFile(options) {
|
||||
var fs = require('fs'),
|
||||
path = './' + options.fileName,
|
||||
file = require(path);
|
||||
|
||||
if (options.version) {
|
||||
file.version = options.version;
|
||||
}
|
||||
|
||||
fs.writeFileSync(path, JSON.stringify(file, null, 2));
|
||||
}
|
||||
|
||||
grunt.registerTask('default', 'Build OpenPGP.js', function() {
|
||||
grunt.task.run(['clean', 'copy:zlib', 'browserify', 'replace', 'uglify', 'npm_pack']);
|
||||
//TODO jshint is not run because of too many discovered issues, once these are addressed it should autorun
|
||||
|
@ -187,6 +217,6 @@ module.exports = function(grunt) {
|
|||
npm.stderr.pipe(process.stderr);
|
||||
});
|
||||
|
||||
// Test/Dev tasks
|
||||
// Test/Dev tasks
|
||||
grunt.registerTask('test', ['copy:npm', 'mochaTest', 'mocha_phantomjs']);
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@ For use in browser, install via bower:
|
|||
|
||||
bower install --save openpgp
|
||||
|
||||
Or Fetch a minified build under [releases](https://github.com/openpgpjs/openpgpjs/releases).
|
||||
Or Fetch a minified build under [dist](https://github.com/openpgpjs/openpgpjs/tree/master/dist).
|
||||
|
||||
The library can be loaded via AMD/require.js or accessed globally via `window.openpgp`.
|
||||
|
||||
|
|
16
bower.json
16
bower.json
|
@ -1,12 +1,17 @@
|
|||
{
|
||||
"name": "openpgpjs",
|
||||
"version": "0.7.2",
|
||||
"name": "openpgp",
|
||||
"version": "0.11.0",
|
||||
"homepage": "http://openpgpjs.org/",
|
||||
"authors": [
|
||||
"OpenPGP Development Team <list@openpgpjs.org> (https://github.com/openpgpjs/openpgpjs/graphs/contributors)"
|
||||
],
|
||||
"description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.",
|
||||
"main": "src/index.js",
|
||||
"main": [
|
||||
"dist/openpgp.js",
|
||||
"dist/openpgp.worker.js",
|
||||
"dist/openpgp.min.js",
|
||||
"dist/openpgp.worker.min.js"
|
||||
],
|
||||
"moduleType": [
|
||||
"amd",
|
||||
"es6",
|
||||
|
@ -23,13 +28,12 @@
|
|||
"license": "LGPL 3.0 or any later version",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"dist/openpgp*.tgz",
|
||||
"dist/*.tgz",
|
||||
"dist/*_debug.js",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"dist",
|
||||
"doc"
|
||||
]
|
||||
}
|
||||
|
||||
|
|
16599
dist/openpgp.js
vendored
Normal file
16599
dist/openpgp.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
dist/openpgp.min.js
vendored
Normal file
8
dist/openpgp.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
193
dist/openpgp.worker.js
vendored
Normal file
193
dist/openpgp.worker.js
vendored
Normal file
|
@ -0,0 +1,193 @@
|
|||
;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
// GPG4Browsers - An OpenPGP implementation in javascript
|
||||
// Copyright (C) 2011 Recurity Labs GmbH
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 3.0 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
window = {}; // to make UMD bundles work
|
||||
|
||||
// Mozilla bind polyfill because phantomjs is stupid
|
||||
if (!Function.prototype.bind) {
|
||||
Function.prototype.bind = function(oThis) {
|
||||
if (typeof this !== "function") {
|
||||
// closest thing possible to the ECMAScript 5 internal IsCallable function
|
||||
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
|
||||
}
|
||||
|
||||
var aArgs = Array.prototype.slice.call(arguments, 1),
|
||||
fToBind = this,
|
||||
FNOP = function() {},
|
||||
fBound = function() {
|
||||
return fToBind.apply(this instanceof FNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
|
||||
};
|
||||
|
||||
FNOP.prototype = this.prototype;
|
||||
fBound.prototype = new FNOP();
|
||||
|
||||
return fBound;
|
||||
};
|
||||
}
|
||||
|
||||
importScripts('openpgp.js');
|
||||
|
||||
var MIN_SIZE_RANDOM_BUFFER = 40000;
|
||||
var MAX_SIZE_RANDOM_BUFFER = 60000;
|
||||
|
||||
window.openpgp.crypto.random.randomBuffer.init(MAX_SIZE_RANDOM_BUFFER);
|
||||
|
||||
self.onmessage = function (event) {
|
||||
var data = null,
|
||||
err = null,
|
||||
msg = event.data,
|
||||
correct = false;
|
||||
|
||||
switch (msg.event) {
|
||||
case 'configure':
|
||||
for (var i in msg.config) {
|
||||
window.openpgp.config[i] = msg.config[i];
|
||||
}
|
||||
break;
|
||||
case 'seed-random':
|
||||
if (!(msg.buf instanceof Uint8Array)) {
|
||||
msg.buf = new Uint8Array(msg.buf);
|
||||
}
|
||||
window.openpgp.crypto.random.randomBuffer.set(msg.buf);
|
||||
break;
|
||||
case 'encrypt-message':
|
||||
if (!msg.keys.length) {
|
||||
msg.keys = [msg.keys];
|
||||
}
|
||||
msg.keys = msg.keys.map(packetlistCloneToKey);
|
||||
window.openpgp.encryptMessage(msg.keys, msg.text).then(function(data) {
|
||||
response({event: 'method-return', data: data});
|
||||
}).catch(function(e) {
|
||||
response({event: 'method-return', err: e.message});
|
||||
});
|
||||
break;
|
||||
case 'sign-and-encrypt-message':
|
||||
if (!msg.publicKeys.length) {
|
||||
msg.publicKeys = [msg.publicKeys];
|
||||
}
|
||||
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
|
||||
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||
window.openpgp.signAndEncryptMessage(msg.publicKeys, msg.privateKey, msg.text).then(function(data) {
|
||||
response({event: 'method-return', data: data});
|
||||
}).catch(function(e) {
|
||||
response({event: 'method-return', err: e.message});
|
||||
});
|
||||
break;
|
||||
case 'decrypt-message':
|
||||
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||
msg.message = packetlistCloneToMessage(msg.message.packets);
|
||||
window.openpgp.decryptMessage(msg.privateKey, msg.message).then(function(data) {
|
||||
response({event: 'method-return', data: data});
|
||||
}).catch(function(e) {
|
||||
response({event: 'method-return', err: e.message});
|
||||
});
|
||||
break;
|
||||
case 'decrypt-and-verify-message':
|
||||
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||
if (!msg.publicKeys.length) {
|
||||
msg.publicKeys = [msg.publicKeys];
|
||||
}
|
||||
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
|
||||
msg.message = packetlistCloneToMessage(msg.message.packets);
|
||||
window.openpgp.decryptAndVerifyMessage(msg.privateKey, msg.publicKeys, msg.message).then(function(data) {
|
||||
response({event: 'method-return', data: data});
|
||||
}).catch(function(e) {
|
||||
response({event: 'method-return', err: e.message});
|
||||
});
|
||||
break;
|
||||
case 'sign-clear-message':
|
||||
msg.privateKeys = msg.privateKeys.map(packetlistCloneToKey);
|
||||
window.openpgp.signClearMessage(msg.privateKeys, msg.text).then(function(data) {
|
||||
response({event: 'method-return', data: data});
|
||||
}).catch(function(e) {
|
||||
response({event: 'method-return', err: e.message});
|
||||
});
|
||||
break;
|
||||
case 'verify-clear-signed-message':
|
||||
if (!msg.publicKeys.length) {
|
||||
msg.publicKeys = [msg.publicKeys];
|
||||
}
|
||||
msg.publicKeys = msg.publicKeys.map(packetlistCloneToKey);
|
||||
var packetlist = window.openpgp.packet.List.fromStructuredClone(msg.message.packets);
|
||||
msg.message = new window.openpgp.cleartext.CleartextMessage(msg.message.text, packetlist);
|
||||
window.openpgp.verifyClearSignedMessage(msg.publicKeys, msg.message).then(function(data) {
|
||||
response({event: 'method-return', data: data});
|
||||
}).catch(function(e) {
|
||||
response({event: 'method-return', err: e.message});
|
||||
});
|
||||
break;
|
||||
case 'generate-key-pair':
|
||||
window.openpgp.generateKeyPair(msg.options).then(function(data) {
|
||||
data.key = data.key.toPacketlist();
|
||||
response({event: 'method-return', data: data});
|
||||
}).catch(function(e) {
|
||||
response({event: 'method-return', err: e.message});
|
||||
});
|
||||
break;
|
||||
case 'decrypt-key':
|
||||
try {
|
||||
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||
correct = msg.privateKey.decrypt(msg.password);
|
||||
if (correct) {
|
||||
data = msg.privateKey.toPacketlist();
|
||||
} else {
|
||||
err = 'Wrong password';
|
||||
}
|
||||
} catch (e) {
|
||||
err = e.message;
|
||||
}
|
||||
response({event: 'method-return', data: data, err: err});
|
||||
break;
|
||||
case 'decrypt-key-packet':
|
||||
try {
|
||||
msg.privateKey = packetlistCloneToKey(msg.privateKey);
|
||||
msg.keyIds = msg.keyIds.map(window.openpgp.Keyid.fromClone);
|
||||
correct = msg.privateKey.decryptKeyPacket(msg.keyIds, msg.password);
|
||||
if (correct) {
|
||||
data = msg.privateKey.toPacketlist();
|
||||
} else {
|
||||
err = 'Wrong password';
|
||||
}
|
||||
} catch (e) {
|
||||
err = e.message;
|
||||
}
|
||||
response({event: 'method-return', data: data, err: err});
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown Worker Event.');
|
||||
}
|
||||
};
|
||||
|
||||
function response(event) {
|
||||
if (window.openpgp.crypto.random.randomBuffer.size < MIN_SIZE_RANDOM_BUFFER) {
|
||||
postMessage({event: 'request-seed'});
|
||||
}
|
||||
postMessage(event);
|
||||
}
|
||||
|
||||
function packetlistCloneToKey(packetlistClone) {
|
||||
var packetlist = window.openpgp.packet.List.fromStructuredClone(packetlistClone);
|
||||
return new window.openpgp.key.Key(packetlist);
|
||||
}
|
||||
|
||||
function packetlistCloneToMessage(packetlistClone) {
|
||||
var packetlist = window.openpgp.packet.List.fromStructuredClone(packetlistClone);
|
||||
return new window.openpgp.message.Message(packetlist);
|
||||
}
|
||||
},{}]},{},[1])
|
||||
;
|
1
dist/openpgp.worker.min.js
vendored
Normal file
1
dist/openpgp.worker.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/*! OpenPGPjs.org this is LGPL licensed code, see LICENSE/our website for more information.- v0.11.0 - 2015-02-16 */!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<d.length;g++)e(d[g]);return e}({1:[function(){function a(a){window.openpgp.crypto.random.randomBuffer.size<d&&postMessage({event:"request-seed"}),postMessage(a)}function b(a){var b=window.openpgp.packet.List.fromStructuredClone(a);return new window.openpgp.key.Key(b)}function c(a){var b=window.openpgp.packet.List.fromStructuredClone(a);return new window.openpgp.message.Message(b)}window={},Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),importScripts("openpgp.min.js");var d=4e4,e=6e4;window.openpgp.crypto.random.randomBuffer.init(e),self.onmessage=function(d){var e=null,f=null,g=d.data,h=!1;switch(g.event){case"configure":for(var i in g.config)window.openpgp.config[i]=g.config[i];break;case"seed-random":g.buf instanceof Uint8Array||(g.buf=new Uint8Array(g.buf)),window.openpgp.crypto.random.randomBuffer.set(g.buf);break;case"encrypt-message":g.keys.length||(g.keys=[g.keys]),g.keys=g.keys.map(b),window.openpgp.encryptMessage(g.keys,g.text).then(function(b){a({event:"method-return",data:b})})["catch"](function(b){a({event:"method-return",err:b.message})});break;case"sign-and-encrypt-message":g.publicKeys.length||(g.publicKeys=[g.publicKeys]),g.publicKeys=g.publicKeys.map(b),g.privateKey=b(g.privateKey),window.openpgp.signAndEncryptMessage(g.publicKeys,g.privateKey,g.text).then(function(b){a({event:"method-return",data:b})})["catch"](function(b){a({event:"method-return",err:b.message})});break;case"decrypt-message":g.privateKey=b(g.privateKey),g.message=c(g.message.packets),window.openpgp.decryptMessage(g.privateKey,g.message).then(function(b){a({event:"method-return",data:b})})["catch"](function(b){a({event:"method-return",err:b.message})});break;case"decrypt-and-verify-message":g.privateKey=b(g.privateKey),g.publicKeys.length||(g.publicKeys=[g.publicKeys]),g.publicKeys=g.publicKeys.map(b),g.message=c(g.message.packets),window.openpgp.decryptAndVerifyMessage(g.privateKey,g.publicKeys,g.message).then(function(b){a({event:"method-return",data:b})})["catch"](function(b){a({event:"method-return",err:b.message})});break;case"sign-clear-message":g.privateKeys=g.privateKeys.map(b),window.openpgp.signClearMessage(g.privateKeys,g.text).then(function(b){a({event:"method-return",data:b})})["catch"](function(b){a({event:"method-return",err:b.message})});break;case"verify-clear-signed-message":g.publicKeys.length||(g.publicKeys=[g.publicKeys]),g.publicKeys=g.publicKeys.map(b);var j=window.openpgp.packet.List.fromStructuredClone(g.message.packets);g.message=new window.openpgp.cleartext.CleartextMessage(g.message.text,j),window.openpgp.verifyClearSignedMessage(g.publicKeys,g.message).then(function(b){a({event:"method-return",data:b})})["catch"](function(b){a({event:"method-return",err:b.message})});break;case"generate-key-pair":window.openpgp.generateKeyPair(g.options).then(function(b){b.key=b.key.toPacketlist(),a({event:"method-return",data:b})})["catch"](function(b){a({event:"method-return",err:b.message})});break;case"decrypt-key":try{g.privateKey=b(g.privateKey),h=g.privateKey.decrypt(g.password),h?e=g.privateKey.toPacketlist():f="Wrong password"}catch(k){f=k.message}a({event:"method-return",data:e,err:f});break;case"decrypt-key-packet":try{g.privateKey=b(g.privateKey),g.keyIds=g.keyIds.map(window.openpgp.Keyid.fromClone),h=g.privateKey.decryptKeyPacket(g.keyIds,g.password),h?e=g.privateKey.toPacketlist():f="Wrong password"}catch(k){f=k.message}a({event:"method-return",data:e,err:f});break;default:throw new Error("Unknown Worker Event.")}}},{}]},{},[1]);
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "openpgp",
|
||||
"description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.",
|
||||
"version": "0.9.0",
|
||||
"version": "0.11.0",
|
||||
"homepage": "http://openpgpjs.org/",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
|
@ -18,6 +18,10 @@
|
|||
},
|
||||
"files": [
|
||||
"src/",
|
||||
"dist/openpgp.js",
|
||||
"dist/openpgp.worker.js",
|
||||
"dist/openpgp.min.js",
|
||||
"dist/openpgp.worker.min.js",
|
||||
"test/unittests.js",
|
||||
"test/general",
|
||||
"test/crypto"
|
||||
|
|
34
release.sh
Executable file
34
release.sh
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/bin/sh
|
||||
|
||||
# abort if tests fail
|
||||
set -e
|
||||
|
||||
# go to root
|
||||
cd `dirname $0`
|
||||
|
||||
if [ "$#" -ne 1 ] ; then
|
||||
echo 'Usage: ./release.sh 0.0.0'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# install dependencies
|
||||
rm -rf node_modules/
|
||||
npm install
|
||||
|
||||
# set version
|
||||
grunt set_version --release=$1
|
||||
|
||||
# build and test
|
||||
npm test
|
||||
|
||||
# Add build files to git
|
||||
sed -i "" '/^dist\/$/d' .gitignore
|
||||
git add dist/ *.json
|
||||
git commit -m "Release new version"
|
||||
git checkout .gitignore
|
||||
git tag v$1
|
||||
git push
|
||||
git push --tag
|
||||
|
||||
# publish to npm
|
||||
npm publish
|
|
@ -37,6 +37,7 @@ module.exports = {
|
|||
compression: enums.compression.zip,
|
||||
integrity_protect: true,
|
||||
rsa_blinding: true,
|
||||
useWebCrypto: true,
|
||||
|
||||
show_version: true,
|
||||
show_comment: true,
|
||||
|
|
|
@ -102,14 +102,18 @@ function DSA() {
|
|||
function verify(hashalgo, s1, s2, m, p, q, g, y) {
|
||||
var hashed_data = util.getLeftNBits(hashModule.digest(hashalgo, m), q.bitLength());
|
||||
var hash = new BigInteger(util.hexstrdump(hashed_data), 16);
|
||||
if (BigInteger.ZERO.compareTo(s1) > 0 ||
|
||||
s1.compareTo(q) > 0 ||
|
||||
BigInteger.ZERO.compareTo(s2) > 0 ||
|
||||
s2.compareTo(q) > 0) {
|
||||
if (BigInteger.ZERO.compareTo(s1) >= 0 ||
|
||||
s1.compareTo(q) >= 0 ||
|
||||
BigInteger.ZERO.compareTo(s2) >= 0 ||
|
||||
s2.compareTo(q) >= 0) {
|
||||
util.print_debug("invalid DSA Signature");
|
||||
return null;
|
||||
}
|
||||
var w = s2.modInverse(q);
|
||||
if (BigInteger.ZERO.compareTo(w) == 0) {
|
||||
util.print_debug("invalid DSA Signature");
|
||||
return null;
|
||||
}
|
||||
var u1 = hash.multiply(w).mod(q);
|
||||
var u2 = s1.multiply(w).mod(q);
|
||||
return g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q);
|
||||
|
|
|
@ -135,7 +135,6 @@ function RSA() {
|
|||
|
||||
function generate(B, E) {
|
||||
var webCrypto = util.getWebCrypto();
|
||||
var promise;
|
||||
|
||||
//
|
||||
// Native RSA keygen using Web Crypto
|
||||
|
@ -144,22 +143,41 @@ function RSA() {
|
|||
if (webCrypto) {
|
||||
var Euint32 = new Uint32Array([parseInt(E, 16)]); // get integer of exponent
|
||||
var Euint8 = new Uint8Array(Euint32.buffer); // get bytes of exponent
|
||||
var keyGenOpt = {
|
||||
name: 'RSASSA-PKCS1-v1_5',
|
||||
modulusLength: B, // the specified keysize in bits
|
||||
publicExponent: Euint8.subarray(0, 3), // take three bytes (max 65537)
|
||||
hash: {
|
||||
name: 'SHA-1' // not required for actual RSA keys, but for crypto api 'sign' and 'verify'
|
||||
}
|
||||
};
|
||||
promise = webCrypto.generateKey(keyGenOpt, true, ['sign', 'verify']);
|
||||
return promise.then(exportKey).then(decodeKey);
|
||||
var keyGenOpt;
|
||||
|
||||
if (window.crypto.subtle) {
|
||||
// current standard spec
|
||||
keyGenOpt = {
|
||||
name: 'RSASSA-PKCS1-v1_5',
|
||||
modulusLength: B, // the specified keysize in bits
|
||||
publicExponent: Euint8.subarray(0, 3), // take three bytes (max 65537)
|
||||
hash: {
|
||||
name: 'SHA-1' // not required for actual RSA keys, but for crypto api 'sign' and 'verify'
|
||||
}
|
||||
};
|
||||
return webCrypto.generateKey(keyGenOpt, true, ['sign', 'verify']).then(exportKey).then(decodeKey);
|
||||
|
||||
} else if (window.crypto.webkitSubtle) {
|
||||
// outdated spec implemented by Webkit
|
||||
keyGenOpt = {
|
||||
name: 'RSA-OAEP',
|
||||
modulusLength: B, // the specified keysize in bits
|
||||
publicExponent: Euint8.subarray(0, 3), // take three bytes (max 65537)
|
||||
};
|
||||
return webCrypto.generateKey(keyGenOpt, true, ['encrypt', 'decrypt']).then(exportKey).then(function(key) {
|
||||
if (key instanceof ArrayBuffer) {
|
||||
// parse raw ArrayBuffer bytes to jwk/json (WebKit/Safari quirk)
|
||||
return decodeKey(JSON.parse(String.fromCharCode.apply(null, new Uint8Array(key))));
|
||||
}
|
||||
return decodeKey(key);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function exportKey(key) {
|
||||
function exportKey(keypair) {
|
||||
// export the generated keys as JsonWebKey (JWK)
|
||||
// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
|
||||
return webCrypto.exportKey('jwk', key.privateKey);
|
||||
return webCrypto.exportKey('jwk', keypair.privateKey);
|
||||
}
|
||||
|
||||
function decodeKey(jwk) {
|
||||
|
@ -185,7 +203,7 @@ function RSA() {
|
|||
// JS code
|
||||
//
|
||||
|
||||
promise = new Promise(function(resolve) {
|
||||
return new Promise(function(resolve) {
|
||||
var key = new keyObject();
|
||||
var rng = new SecureRandom();
|
||||
var qs = B >> 1;
|
||||
|
@ -223,8 +241,6 @@ function RSA() {
|
|||
|
||||
resolve(key);
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
this.encrypt = encrypt;
|
||||
|
|
|
@ -46,14 +46,32 @@ if (typeof Promise === 'undefined') {
|
|||
require('es6-promise').polyfill();
|
||||
}
|
||||
|
||||
var asyncProxy; // instance of the asyncproxy
|
||||
var asyncProxy = null; // instance of the asyncproxy
|
||||
|
||||
/**
|
||||
* Set the path for the web worker script and create an instance of the async proxy
|
||||
* @param {String} path relative path to the worker scripts
|
||||
* @param {String} path relative path to the worker scripts, default: 'openpgp.worker.js'
|
||||
* @param {Object} [options.worker=Object] alternative to path parameter:
|
||||
* web worker initialized with 'openpgp.worker.js'
|
||||
* @return {Boolean} true if worker created successfully
|
||||
*/
|
||||
function initWorker(path) {
|
||||
asyncProxy = new AsyncProxy(path);
|
||||
function initWorker(path, options) {
|
||||
if (options && options.worker || typeof window !== 'undefined' && window.Worker) {
|
||||
options = options || {};
|
||||
options.config = this.config;
|
||||
asyncProxy = new AsyncProxy(path, options);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the async proxy if the worker was initialized with openpgp.initWorker()
|
||||
* @return {module:worker/async_proxy~AsyncProxy|null} the async proxy or null if not initialized
|
||||
*/
|
||||
function getWorker() {
|
||||
return asyncProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,7 +86,7 @@ function encryptMessage(keys, text) {
|
|||
keys = [keys];
|
||||
}
|
||||
|
||||
if (useWorker()) {
|
||||
if (asyncProxy) {
|
||||
return asyncProxy.encryptMessage(keys, text);
|
||||
}
|
||||
|
||||
|
@ -95,7 +113,7 @@ function signAndEncryptMessage(publicKeys, privateKey, text) {
|
|||
publicKeys = [publicKeys];
|
||||
}
|
||||
|
||||
if (useWorker()) {
|
||||
if (asyncProxy) {
|
||||
return asyncProxy.signAndEncryptMessage(publicKeys, privateKey, text);
|
||||
}
|
||||
|
||||
|
@ -119,7 +137,7 @@ function signAndEncryptMessage(publicKeys, privateKey, text) {
|
|||
* @static
|
||||
*/
|
||||
function decryptMessage(privateKey, msg) {
|
||||
if (useWorker()) {
|
||||
if (asyncProxy) {
|
||||
return asyncProxy.decryptMessage(privateKey, msg);
|
||||
}
|
||||
|
||||
|
@ -145,7 +163,7 @@ function decryptAndVerifyMessage(privateKey, publicKeys, msg) {
|
|||
publicKeys = [publicKeys];
|
||||
}
|
||||
|
||||
if (useWorker()) {
|
||||
if (asyncProxy) {
|
||||
return asyncProxy.decryptAndVerifyMessage(privateKey, publicKeys, msg);
|
||||
}
|
||||
|
||||
|
@ -174,7 +192,7 @@ function signClearMessage(privateKeys, text) {
|
|||
privateKeys = [privateKeys];
|
||||
}
|
||||
|
||||
if (useWorker()) {
|
||||
if (asyncProxy) {
|
||||
return asyncProxy.signClearMessage(privateKeys, text);
|
||||
}
|
||||
|
||||
|
@ -199,7 +217,7 @@ function verifyClearSignedMessage(publicKeys, msg) {
|
|||
publicKeys = [publicKeys];
|
||||
}
|
||||
|
||||
if (useWorker()) {
|
||||
if (asyncProxy) {
|
||||
return asyncProxy.verifyClearSignedMessage(publicKeys, msg);
|
||||
}
|
||||
|
||||
|
@ -229,7 +247,7 @@ function verifyClearSignedMessage(publicKeys, msg) {
|
|||
*/
|
||||
function generateKeyPair(options) {
|
||||
// use web worker if web crypto apis are not supported
|
||||
if (!util.getWebCrypto() && useWorker()) {
|
||||
if (!util.getWebCrypto() && asyncProxy) {
|
||||
return asyncProxy.generateKeyPair(options);
|
||||
}
|
||||
|
||||
|
@ -259,22 +277,6 @@ function generateKeyPair(options) {
|
|||
// helper functions
|
||||
//
|
||||
|
||||
/**
|
||||
* Are we in a browser and do we support worker?
|
||||
*/
|
||||
function useWorker() {
|
||||
if (typeof window === 'undefined' || !window.Worker) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!asyncProxy) {
|
||||
console.log('You need to set the worker path!');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command pattern that wraps synchronous code into a promise
|
||||
* @param {function} cmd The synchronous function with a return value
|
||||
|
@ -307,6 +309,7 @@ function onError(message, error) {
|
|||
}
|
||||
|
||||
exports.initWorker = initWorker;
|
||||
exports.getWorker = getWorker;
|
||||
exports.encryptMessage = encryptMessage;
|
||||
exports.signAndEncryptMessage = signAndEncryptMessage;
|
||||
exports.decryptMessage = decryptMessage;
|
||||
|
|
|
@ -71,3 +71,9 @@ module.exports.fromClone = function (clone) {
|
|||
keyid.bytes = clone.bytes;
|
||||
return keyid;
|
||||
};
|
||||
|
||||
module.exports.fromId = function (hex) {
|
||||
var keyid = new Keyid();
|
||||
keyid.read(util.hex2bin(hex));
|
||||
return keyid;
|
||||
};
|
||||
|
|
|
@ -320,8 +320,8 @@ module.exports = {
|
|||
return;
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined' && window.crypto && window.crypto.subtle) {
|
||||
return window.crypto.subtle;
|
||||
if (typeof window !== 'undefined' && window.crypto) {
|
||||
return window.crypto.subtle || window.crypto.webkitSubtle;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -38,9 +38,16 @@ var INITIAL_RANDOM_SEED = 50000, // random bytes seeded to worker
|
|||
* Initializes a new proxy and loads the web worker
|
||||
* @constructor
|
||||
* @param {String} path The path to the worker or 'openpgp.worker.js' by default
|
||||
* @param {Object} [options.config=Object] config The worker configuration
|
||||
* @param {Object} [options.worker=Object] alternative to path parameter:
|
||||
* web worker initialized with 'openpgp.worker.js'
|
||||
*/
|
||||
function AsyncProxy(path) {
|
||||
this.worker = new Worker(path || 'openpgp.worker.js');
|
||||
function AsyncProxy(path, options) {
|
||||
if (options && options.worker) {
|
||||
this.worker = options.worker;
|
||||
} else {
|
||||
this.worker = new Worker(path || 'openpgp.worker.js');
|
||||
}
|
||||
this.worker.onmessage = this.onMessage.bind(this);
|
||||
this.worker.onerror = function(e) {
|
||||
throw new Error('Unhandled error in openpgp worker: ' + e.message + ' (' + e.filename + ':' + e.lineno + ')');
|
||||
|
@ -48,6 +55,9 @@ function AsyncProxy(path) {
|
|||
this.seedRandom(INITIAL_RANDOM_SEED);
|
||||
// FIFO
|
||||
this.tasks = [];
|
||||
if (options && options.config) {
|
||||
this.worker.postMessage({event: 'configure', config: options.config});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -53,6 +53,11 @@ self.onmessage = function (event) {
|
|||
correct = false;
|
||||
|
||||
switch (msg.event) {
|
||||
case 'configure':
|
||||
for (var i in msg.config) {
|
||||
window.openpgp.config[i] = msg.config[i];
|
||||
}
|
||||
break;
|
||||
case 'seed-random':
|
||||
if (!(msg.buf instanceof Uint8Array)) {
|
||||
msg.buf = new Uint8Array(msg.buf);
|
||||
|
|
|
@ -172,6 +172,25 @@ var priv_key_de =
|
|||
expect(privKeyDE).to.exist;
|
||||
}
|
||||
|
||||
describe('Init Worker', function() {
|
||||
|
||||
this.timeout(0);
|
||||
|
||||
it('openpgp.getWorker method', function (done) {
|
||||
expect(openpgp.getWorker()).to.be.null;
|
||||
var workerAvailable = openpgp.initWorker('../dist/openpgp.worker.js');
|
||||
expect(workerAvailable).to.be.true;
|
||||
expect(openpgp.getWorker()).to.exist;
|
||||
privKeyRSA = openpgp.key.readArmored(priv_key_rsa).keys[0];
|
||||
expect(privKeyRSA.primaryKey.isDecrypted).to.be.false;
|
||||
openpgp.getWorker().decryptKeyPacket(privKeyRSA, [privKeyRSA.primaryKey.getKeyId()], 'hello world').then(function(key) {
|
||||
expect(key.primaryKey.isDecrypted).to.be.true;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('High level API', function() {
|
||||
|
||||
this.timeout(0);
|
||||
|
@ -181,8 +200,21 @@ describe('High level API', function() {
|
|||
initKeys();
|
||||
});
|
||||
|
||||
describe('Encryption', function() {
|
||||
describe('Main', function(){
|
||||
it('Configuration', function(done){
|
||||
openpgp.config.show_version = false;
|
||||
openpgp.config.commentstring = 'different';
|
||||
openpgp.initWorker('../dist/openpgp.worker.js');
|
||||
openpgp.encryptMessage([pubKeyRSA], plaintext).then(function(data) {
|
||||
expect(data).to.exist;
|
||||
expect(data).not.to.match(/^Version:/);
|
||||
expect(data).to.match(/Comment: different/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Encryption', function() {
|
||||
it('RSA: encryptMessage async', function (done) {
|
||||
openpgp.encryptMessage([pubKeyRSA], plaintext).then(function(data) {
|
||||
expect(data).to.exist;
|
||||
|
|
Loading…
Reference in New Issue
Block a user