Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
var child_process = require('child_process');
child_process.exec('npm -v', function (error, stdout, stderr) {
var version = stdout.toString();
var pure_js = version[0] === '2';
console.log(pure_js);
if (pure_js) {
console.log('PURE JS');
} else {
child_process.exec('npm install git+https://github.com/rynomad/ecc.git');
}
});
17 changes: 0 additions & 17 deletions install.sh

This file was deleted.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "crypto.subtle for node.js",
"main": "src/main.js",
"scripts": {
"install": "./install.sh",
"install": "node install.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
Expand All @@ -22,6 +22,7 @@
"license": "MIT",
"dependencies": {
"ecc-jsbn": "0.0.1",
"ecc-qj": "git+https://github.com/mitar/ecc.git#4087e38646d2a375c3c2ce0a3d1881b3c35d9dab",
"node-forge": "^0.6.20",
"polyfill-promise": "^4.0.1",
"sjcl": "^1.0.3"
Expand Down
10 changes: 10 additions & 0 deletions src/bufferize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function Bufferize (result){
if (result instanceof ArrayBuffer)
result = new Uint8Array(result);
if (result instanceof Uint8Array)
result = new Buffer(result);

return result;
}

module.exports = Bufferize;
9 changes: 1 addition & 8 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var Browser = require("./use_node.js")
var OPS = ["generateKey", "importKey", "exportKey", "sign", "verify", "encrypt", "decrypt", "digest", "deriveKey", "deriveBits"]
var nonce = require("crypto").randomBytes(64).toString("hex")
var Bufferize = require('./bufferize')
global.FORGE = require("./forgeless.js")
global.Promise = require("polyfill-promise")
var Subtle = {}
Expand All @@ -25,14 +26,6 @@ function makeArgArray (args){
return ar;
}

function Bufferize (result){
if (result instanceof ArrayBuffer)
result = new Uint8Array(result);
if (result instanceof Uint8Array)
result = new Buffer(result);

return result;
}
function makeRoutine(routine){
return function(){
var routineArgs = makeArgArray(arguments)
Expand Down
10 changes: 8 additions & 2 deletions src/node/algorithms/AES-GCM.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var sjcl = require("sjcl")
, Algorithm = require("./abstract")("AES-GCM")
, Bufferize = require('./../../bufferize')
, AES = require("./shared/AES")
, secret = Algorithm.types.secret.usage

Expand All @@ -11,8 +12,13 @@ secret.decrypt = createDecrypt;
module.exports = Algorithm;

function getParams(alg, data){
return { iv : sjcl.codec.hex.toBits(alg.iv.toString('hex'))
, add : sjcl.codec.hex.toBits(alg.additionalData.toString('hex'))
var iv = Bufferize(alg.iv);
var additionalData = alg.additionalData ? Bufferize(alg.additionalData) : new Buffer([]);

data = data ? Bufferize(data) : new Buffer([]);

return { iv : sjcl.codec.hex.toBits(iv.toString('hex'))
, add : sjcl.codec.hex.toBits(additionalData.toString('hex'))
, data : sjcl.codec.hex.toBits(data.toString('hex'))
};
}
Expand Down
54 changes: 54 additions & 0 deletions src/node/algorithms/ECDSA.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
var Algorithm = require("./abstract")("ECDSA")
, ECC = require("./shared/ECC")
, forge = require("node-forge")
, types = Algorithm.types
, public = types.public.usage
, private = types.private.usage;

ECC(Algorithm);

Algorithm.checkParams = checkParams;

public.verify = createVerify;
private.sign = createSign;

module.exports = Algorithm;

function checkParams(format, algorithm, usages) {
}

function createSign(key, alg1) {
return function ECDSA_SIGN(alg, buf) {
var forgehashKey = alg.hash.name.replace(/-/g, '').toLowerCase();
var md = forge.md[forgehashKey].create();
md.update(buf.toString("binary"));
var digest = md.digest().toHex();
var signature = key.sign(new Buffer(digest, 'hex'));
// Signature is DER encoded, remove it.
var decodedSignature = forge.asn1.fromDer(signature.toString("binary"));
// We take only the last 32 bytes because values could be padded with 0 at the beginning.
return Buffer.concat([
new Buffer(decodedSignature.value[0].value, 'binary').slice(-32),
new Buffer(decodedSignature.value[1].value, 'binary').slice(-32)
]);
};
}

function createVerify(key, alg1){
return function ECDSA_VERIFY(alg, buf, sig) {
var forgehashKey = alg.hash.name.replace(/-/g, '').toLowerCase();
var md = forge.md[forgehashKey].create();
md.update(buf.toString("binary"));
var digest = md.digest().getBytes();
var sigPart1 = sig.slice(0, 32);
var sigPart2 = sig.slice(32, 64);
var asn1 = forge.asn1;
var derSignature = asn1.toDer(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, sigPart1.toString("binary")),
asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false, sigPart2.toString("binary"))
])).getBytes();
return key.verifySignature(new Buffer(digest, 'binary'), new Buffer(derSignature, 'binary'));
}
}

module.exports = Algorithm;
1 change: 1 addition & 0 deletions src/node/algorithms/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ exports["RSASSA-PKCS1-v1_5"] = require("./RSASSA-PKCS1-v1_5");
exports["HMAC"] = require("./HMAC")
exports["AES-GCM"] = require("./AES-GCM")
exports["ECDH"] = require("./ECDH")
exports["ECDSA"] = require("./ECDSA")
14 changes: 9 additions & 5 deletions src/node/algorithms/shared/AES.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
var sjcl = require("sjcl");
var sjcl = require("sjcl"),
crypto = require("crypto");

function AES_generateKey(noop){
return;
function AES_generateKey(algorithm){
return raw_import(crypto.randomBytes(algorithm.length / 8));
}

function raw_import(buf){
return new sjcl.cipher.aes(sjcl.codec.hex.toBits(buf.toString("hex")));
var key = new sjcl.cipher.aes(sjcl.codec.hex.toBits(buf.toString("hex")));
key._raw = buf;
return key;
}

function raw_export(key){
return key;
return key._raw;
}

function AES(Algorithm){
Algorithm.formats.raw.import = raw_import;
Algorithm.formats.raw.export = raw_export;
Algorithm.generate = AES_generateKey;
return;
}

Expand Down
24 changes: 21 additions & 3 deletions src/node/algorithms/shared/ECC.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
var ecc = require("./ecc.node.js")
, spkiECCPad = new Buffer("3056301006042b81047006082a8648ce3d030107034200","hex");
, spkiECCPad = new Buffer("3059301306072a8648ce3d020106082a8648ce3d030107034200","hex")
, pkcsPad1 = new Buffer("308187020100301306072A8648CE3D020106082A8648CE3D030107046D306B0201010420", "hex")
, pkcsPad2 = new Buffer("A144034200", "hex");

function getCurveKey(namedCurve){
return ("sec" + namedCurve.replace(/-/g, '').toLowerCase() + "r1");
Expand All @@ -16,7 +18,6 @@ function spki_export(Key){
}

function raw_export(Key){
console.log("raw ecc export")
return new Buffer(Key.PublicKey);
}

Expand All @@ -29,6 +30,19 @@ function raw_import(publicBytes, alg){
return new ecc.ECKey(curve, publicBytes, true);
}

function pkcs8_import(privateBytes, algorithm) {
var curvekey = getCurveKey(algorithm.namedCurve)
, curve = ecc.ECCurves[curvekey];

curve.legacy = true;

return new ecc.ECKey(curve, privateBytes.slice(pkcsPad1.length, pkcsPad1.length + 32), false);
}

function pkcs8_export(Key) {
return Buffer.concat([pkcsPad1, Key.PrivateKey, pkcsPad2, raw_export(Key)]);
}

function generate(alg){
var curvekey = getCurveKey(alg.namedCurve)
, curve = ecc.ECCurves[curvekey];
Expand All @@ -41,7 +55,8 @@ function generate(alg){
function ECC(Algorithm){
var formats = Algorithm.formats
, raw = formats.raw
, spki = formats.spki;
, spki = formats.spki
, pkcs8 = formats.pkcs8;

// attach common generator
Algorithm.generate = generate;
Expand All @@ -53,6 +68,9 @@ function ECC(Algorithm){
spki.import = spki_import;
spki.export = spki_export;

pkcs8.import = pkcs8_import;
pkcs8.export = pkcs8_export;

return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/node/algorithms/shared/RSA.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function generate(algorithm){
pos++;
}

return forge.rsa.generateKeyPair({bits: algorithm.modulousLength , e: exp});
return forge.rsa.generateKeyPair({bits: algorithm.modulusLength , e: exp});
}


Expand Down
7 changes: 6 additions & 1 deletion src/node/generateKey.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ function generateKey(algorithm, exportable, usages, nonce){

//construct the return object from the scaffold
Object.keys(_scaf).forEach(function(type){
_res[_alg.types[type].returnLabel] = new CryptoKey(_key, type, _scaf[type]._exp, _scaf[type]._uses, nonce);
if (_alg.types[type].returnLabel) {
_res[_alg.types[type].returnLabel] = new CryptoKey(_key, type, _scaf[type]._exp, _scaf[type]._uses, nonce);
}
else {
_res = new CryptoKey(_key, type, _scaf[type]._exp, _scaf[type]._uses, nonce);
}
})

//special case... ECDH public keys don't have they're own usage, but are still needed as params in deriveKey/Bits
Expand Down