npm test and grunt browsertest can run side by side now; npm tests pass, browser stuck on problem related to asn1.js

This commit is contained in:
Mahrud Sayrafi 2018-01-04 01:32:04 -08:00 committed by Sanjana Rajan
parent 21ae66c604
commit dcff16d32b
5 changed files with 93 additions and 45 deletions

View File

@ -87,6 +87,31 @@ module.exports = function(grunt) {
plugin: [ 'browserify-derequire' ]
}
},
openpgp_browser: {
files: {
'dist/openpgp_browser.js': [ './src/index.js' ]
},
options: {
browserifyOptions: {
debug: true,
standalone: 'openpgp'
},
external: [ 'crypto', 'node-localstorage', 'node-fetch' ],
transform: [
["babelify", {
plugins: ["transform-async-to-generator",
"syntax-async-functions",
"transform-regenerator",
"transform-runtime"],
ignore: ['*.min.js'],
presets: [
"es2015"
]
}]
],
plugin: [ 'browserify-derequire' ]
}
},
worker: {
files: {
'dist/openpgp.worker.js': [ './src/worker/worker.js' ]
@ -97,7 +122,7 @@ module.exports = function(grunt) {
'test/lib/unittests-bundle.js': [ './test/unittests.js' ]
},
options: {
external: [ 'crypto', 'buffer' , 'node-localstorage', 'node-fetch', 'openpgp', '../../dist/openpgp', '../../../dist/openpgp' ]
external: [ 'crypto', 'node-localstorage', 'node-fetch', 'openpgp', '../../dist/openpgp' ]
}
}
},
@ -190,7 +215,7 @@ module.exports = function(grunt) {
}
},
copy: {
browsertest: {
browser: {
expand: true,
flatten: true,
cwd: 'node_modules/',
@ -262,6 +287,7 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-saucelabs');
grunt.loadNpmTasks('grunt-keepalive');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('set_version', function() {
@ -304,6 +330,7 @@ module.exports = function(grunt) {
// Test/Dev tasks
grunt.registerTask('test', [ 'eslint', 'mochaTest']);
grunt.registerTask('coverage', ['mocha_istanbul:coverage']);
grunt.registerTask('saucelabs', ['default', 'copy:browsertest', 'connect:test', 'saucelabs-mocha']);
grunt.registerTask('saucelabs', ['default', 'copy:browser', 'connect:test', 'saucelabs-mocha']);
grunt.registerTask('browsertest', ['browserify:openpgp_browser', 'copy:browser', 'connect:test', 'keepalive']);
};

View File

@ -27,16 +27,27 @@
'use strict';
import ASN1 from 'asn1.js';
import {ec as EC} from 'elliptic';
import {KeyPair} from './key.js';
import BigInteger from '../jsbn.js';
import config from '../../../config';
import enums from '../../../enums.js';
import util from '../../../util.js';
import base64 from '../../../encoding/base64.js';
const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto();
var ECPrivateKey = ASN1.define('ECPrivateKey', function() {
this.seq().obj(
this.key('r').int(), // FIXME int or BN?
this.key('s').int() // FIXME int or BN?
);
});
var webCurves = [], nodeCurves = [];
if (webCrypto && config.use_native) {
// see https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API/Supported_algorithms
@ -87,7 +98,9 @@ const curves = {
node: false, // FIXME nodeCurves.includes('secp256k1'),
// this is because jwk-to-pem does not support this curve.
web: false
}
},
curve25519 : {},
ed25519 : {}
};
function Curve(name, {oid, hash, cipher, namedCurve, opensslCurve, hashName, node, web}) {
@ -114,7 +127,7 @@ Curve.prototype.keyFromPublic = function (pub) {
Curve.prototype.genKeyPair = async function () {
var keyPair;
if (webCrypto && config.use_native && this.web) {
keyPair = await webGenKeyPair(this.namedCurve);
keyPair = await webGenKeyPair(this.namedCurve, "ECDSA"); // FIXME
} else if (nodeCrypto && config.use_native && this.node) {
keyPair = await nodeGenKeyPair(this.opensslCurve);
} else {
@ -163,24 +176,26 @@ module.exports = {
//////////////////////////
async function webGenKeyPair(namedCurve) {
async function webGenKeyPair(namedCurve, algorithm) {
try {
var keyPair = await webCrypto.generateKey(
var webCryptoKey = await webCrypto.generateKey(
{
name: "ECDSA", // FIXME or "ECDH"
// "P-256", "P-384", or "P-521"
name: algorithm === "ECDH" ? "ECDH" : "ECDSA",
namedCurve: namedCurve
},
// TODO whether the key is extractable (i.e. can be used in exportKey)
false,
// FIXME this can be any combination of "sign" and "verify"
// or "deriveKey" and "deriveBits" for ECDH
["sign", "verify"]
true,
algorithm === "ECDH" ? ["deriveKey", "deriveBits"] : ["sign", "verify"]
);
var privateKey = await webCrypto.exportKey("jwk", webCryptoKey.privateKey);
var publicKey = await webCrypto.exportKey("jwk", webCryptoKey.publicKey);
return {
pub: keyPair.publicKey.encode(), // FIXME encoding
priv: keyPair.privateKey.toArray() // FIXME encoding
pub: {
x: base64.decode(publicKey.x, 'base64url'),
y: base64.decode(publicKey.y, 'base64url')
},
priv: base64.decode(privateKey.d, 'base64url')
};
} catch(err) {
throw new Error(err);

View File

@ -33,12 +33,13 @@ import curves from './curves.js';
import BigInteger from '../jsbn.js';
import config from '../../../config';
import enums from '../../../enums.js';
import util from '../../../util.js'
import util from '../../../util.js';
import base64 from '../../../encoding/base64.js';
const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto();
var ECDSASignature = ASN1.define('ecdsa-sig', function() {
var ECDSASignature = ASN1.define('ECDSASignature', function() {
this.seq().obj(
this.key('r').int(), // FIXME int or BN?
this.key('s').int() // FIXME int or BN?
@ -115,9 +116,9 @@ async function webSign(curve, hash_algo, m, keyPair) {
{
"kty": "EC",
"crv": curve.namedCurve,
"x": keyPair.getPublic().getX().toBuffer().base64Slice(),
"y": keyPair.getPublic().getY().toBuffer().base64Slice(),
"d": keyPair.getPrivate().toBuffer().base64Slice(),
"x": base64.encode(new Uint8Array(keyPair.getPublic().getX().toArray()), null, 'base64url'),
"y": base64.encode(new Uint8Array(keyPair.getPublic().getY().toArray()), null, 'base64url'),
"d": base64.encode(new Uint8Array(keyPair.getPrivate()), null, 'base64url'),
"use": "sig",
"kid": "ECDSA Private Key"
},
@ -151,8 +152,8 @@ async function webVerify(curve, hash_algo, signature, m, publicKey) {
{
"kty": "EC",
"crv": curve.namedCurve,
"x": publicKey.getX().toBuffer().base64Slice(),
"y": publicKey.getY().toBuffer().base64Slice(),
"x": base64.encode(new Uint8Array(publicKey.getX().toArray()), null, 'base64url'),
"y": base64.encode(new Uint8Array(publicKey.getY().toArray()), null, 'base64url'),
"use": "sig",
"kid": "ECDSA Public Key"
},
@ -189,9 +190,9 @@ async function nodeSign(curve, hash_algo, message, keyPair) {
{
"kty": "EC",
"crv": curve.namedCurve,
"x": keyPair.getPublic().getX().toBuffer().base64Slice(),
"y": keyPair.getPublic().getY().toBuffer().base64Slice(),
"d": keyPair.getPrivate().toBuffer().base64Slice(),
"x": base64.encode(new Uint8Array(keyPair.getPublic().getX().toArray())),
"y": base64.encode(new Uint8Array(keyPair.getPublic().getY().toArray())),
"d": base64.encode(new Uint8Array(keyPair.getPrivate().toArray())),
"use": "sig",
"kid": "ECDSA Private Key"
},
@ -223,8 +224,8 @@ async function nodeVerify(curve, hash_algo, signature, message, publicKey) {
{
"kty": "EC",
"crv": curve.namedCurve,
"x": publicKey.getX().toBuffer().base64Slice(),
"y": publicKey.getY().toBuffer().base64Slice(),
"x": base64.encode(new Uint8Array(publicKey.getX().toArray())),
"y": base64.encode(new Uint8Array(publicKey.getY().toArray())),
"use": "sig",
"kid": "ECDSA Public Key"
},

View File

@ -18,6 +18,7 @@
'use strict';
var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var b64u = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
/**
* Convert binary array to radix-64
@ -25,8 +26,9 @@ var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
* @returns {string} radix-64 version of input string
* @static
*/
function s2r(t, o) {
function s2r(t, o, u) {
// TODO check btoa alternative
var b64 = (u === "base64url") ? b64u : b64s;
var a, c, n;
var r = o ? o : [],
l = 0,
@ -36,21 +38,21 @@ function s2r(t, o) {
for (n = 0; n < tl; n++) {
c = t[n];
if (s === 0) {
r.push(b64s.charAt((c >> 2) & 63));
r.push(b64.charAt((c >> 2) & 63));
a = (c & 3) << 4;
} else if (s === 1) {
r.push(b64s.charAt(a | ((c >> 4) & 15)));
r.push(b64.charAt(a | ((c >> 4) & 15)));
a = (c & 15) << 2;
} else if (s === 2) {
r.push(b64s.charAt(a | ((c >> 6) & 3)));
r.push(b64.charAt(a | ((c >> 6) & 3)));
l += 1;
if ((l % 60) === 0) {
if ((l % 60) === 0 && !u) {
r.push("\n");
}
r.push(b64s.charAt(c & 63));
r.push(b64.charAt(c & 63));
}
l += 1;
if ((l % 60) === 0) {
if ((l % 60) === 0 && !u) {
r.push("\n");
}
@ -60,16 +62,18 @@ function s2r(t, o) {
}
}
if (s > 0) {
r.push(b64s.charAt(a));
r.push(b64.charAt(a));
l += 1;
if ((l % 60) === 0) {
if ((l % 60) === 0 && !u) {
r.push("\n");
}
r.push('=');
l += 1;
if (u !== 'base64url') {
r.push('=');
l += 1;
}
}
if (s === 1) {
if ((l % 60) === 0) {
if (s === 1 && u !== 'base64url') {
if ((l % 60) === 0 && !u) {
r.push("\n");
}
r.push('=');
@ -87,8 +91,9 @@ function s2r(t, o) {
* @returns {Uint8Array} binary array version of input string
* @static
*/
function r2s(t) {
function r2s(t, u) {
// TODO check atob alternative
var b64 = (u === "base64url") ? b64u : b64s;
var c, n;
var r = [],
s = 0,
@ -96,7 +101,7 @@ function r2s(t) {
var tl = t.length;
for (n = 0; n < tl; n++) {
c = b64s.indexOf(t.charAt(n));
c = b64.indexOf(t.charAt(n));
if (c >= 0) {
if (s) {
r.push(a | ((c >> (6 - s)) & 255));

View File

@ -10,11 +10,11 @@
<div id="mocha"></div>
<!-- libs -->
<script src="../dist/openpgp.js"></script>
<script src="../dist/openpgp_browser.js"></script>
<script src="lib/chai.js"></script>
<script src="lib/mocha.js"></script>
<script src="lib/fetch.js"></script>
<script>
] <script>
mocha.setup('bdd');
mocha.timeout(240000);
</script>