UNPKG

triplesec

Version:

A CommonJS-compliant system for secure encryption of smallish secrets

853 lines (808 loc) 29.2 kB
// Generated by IcedCoffeeScript 108.0.8 (function() { var AES, Base, CURRENT_VERSION, Concat, Encryptor, HMAC_SHA256, KECCAK, PBKDF2, SHA3STD, SHA512, Scrypt, TwoFish, V, WordArray, XOR, ctr, encrypt, iced, make_esc, prng, salsa20, util, __iced_k, __iced_k_noop, _ref, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; iced = require('iced-runtime'); __iced_k = __iced_k_noop = function() {}; WordArray = require('./wordarray').WordArray; salsa20 = require('./salsa20'); AES = require('./aes').AES; TwoFish = require('./twofish').TwoFish; ctr = require('./ctr'); _ref = require('./combine'), XOR = _ref.XOR, Concat = _ref.Concat; SHA512 = require('./sha512').SHA512; SHA3STD = require('./sha3std').SHA3STD; KECCAK = require('./keccak').KECCAK; PBKDF2 = require('./pbkdf2').PBKDF2; Scrypt = require('./scrypt').Scrypt; util = require('./util'); prng = require('./prng'); make_esc = require('iced-error').make_esc; HMAC_SHA256 = require('./hmac').HMAC_SHA256; V = { "1": { header: [0x1c94d7de, 1], salt_size: 8, xsalsa20_rev: true, kdf: { klass: PBKDF2, opts: { c: 1024, klass: XOR } }, use_twofish: true, hmac_hashes: [SHA512, KECCAK], hmac_key_size: 768 / 8, version: 1 }, "2": { header: [0x1c94d7de, 2], salt_size: 16, xsalsa20_rev: true, kdf: { klass: Scrypt, opts: { c: 64, klass: XOR, N: 12, r: 8, p: 1 } }, use_twofish: true, hmac_hashes: [SHA512, KECCAK], hmac_key_size: 768 / 8, version: 2 }, "3": { header: [0x1c94d7de, 3], salt_size: 16, xsalsa20_rev: false, kdf: { klass: Scrypt, opts: { c: 1, klass: HMAC_SHA256, N: 15, r: 8, p: 1 } }, use_twofish: true, hmac_hashes: [SHA512, KECCAK], hmac_key_size: 768 / 8, version: 3 }, "4": { header: [0x1c94d7de, 4], salt_size: 16, xsalsa20_rev: false, kdf: { klass: Scrypt, opts: { c: 1, klass: HMAC_SHA256, N: 15, r: 8, p: 1 } }, hmac_key_size: 768 / 8, use_twofish: false, hmac_hashes: [SHA512, SHA3STD], version: 4 } }; exports.CURRENT_VERSION = CURRENT_VERSION = 4; Base = (function() { function Base(_arg) { var key, version; key = _arg.key, version = _arg.version; this.version = V[version != null ? version : CURRENT_VERSION]; if (this.version == null) { throw new Error("unknown version: " + version); } this.set_key(key); this.derived_keys = {}; } Base.prototype.kdf = function(_arg, cb) { var args, dkLen, end, extra_keymaterial, i, k, key, keys, len, lens, order, progress_hook, raw, salt, salt_hex, v, ___iced_passed_deferral, __iced_deferrals, __iced_k; __iced_k = __iced_k_noop; ___iced_passed_deferral = iced.findDeferral(arguments); salt = _arg.salt, extra_keymaterial = _arg.extra_keymaterial, progress_hook = _arg.progress_hook; (function(_this) { return (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.kdf" }); _this._check_scrubbed(_this.key, "in KDF", cb, __iced_deferrals.defer({ lineno: 121 })); __iced_deferrals._fulfill(); }); })(this)((function(_this) { return function() { salt_hex = salt.to_hex(); key = _this.key.clone(); (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.kdf" }); _this._check_scrubbed(key, "KDF", cb, __iced_deferrals.defer({ lineno: 129 })); __iced_deferrals._fulfill(); })(function() { (function(__iced_k) { if ((keys = _this.derived_keys[salt_hex]) == null) { _this._kdf = new _this.version.kdf.klass(_this.version.kdf.opts); lens = { hmac: _this.version.hmac_key_size, aes: AES.keySize, salsa20: salsa20.Salsa20.keySize }; if (_this.version.use_twofish) { lens.twofish = TwoFish.keySize; } if (_this.version.use_twofish) { order = ['hmac', 'aes', 'twofish', 'salsa20']; } else { order = ['hmac', 'aes', 'salsa20']; } dkLen = extra_keymaterial || 0; for (k in lens) { v = lens[k]; dkLen += v; } args = { dkLen: dkLen, key: key, progress_hook: progress_hook, salt: salt }; (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.kdf" }); _this._kdf.run(args, __iced_deferrals.defer({ assign_fn: (function() { return function() { return raw = arguments[0]; }; })(), lineno: 152 })); __iced_deferrals._fulfill(); })(function() { var _i, _len; keys = {}; i = 0; for (_i = 0, _len = order.length; _i < _len; _i++) { k = order[_i]; v = lens[k]; len = v / 4; end = i + len; keys[k] = new WordArray(raw.words.slice(i, end)); i = end; } keys.extra = (new WordArray(raw.words.slice(end))).to_buffer(); return __iced_k(_this.derived_keys[salt_hex] = keys); }); } else { return __iced_k(); } })(function() { return cb(null, keys); }); }); }; })(this)); }; Base.prototype.set_key = function(key) { var wakey; if (key != null) { wakey = WordArray.from_buffer(key); if (!this.key || !this.key.equal(wakey)) { this.scrub(); return this.key = wakey; } } else { return this.scrub(); } }; Base.prototype._check_scrubbed = function(key, where, ecb, okcb) { if ((key != null) && !key.is_scrubbed()) { return okcb(); } else { return ecb(new Error("" + where + ": Failed due to scrubbed key!"), null); } }; Base.prototype.sign = function(_arg, cb) { var combine_klasses, input, key, out, progress_hook, salt, ___iced_passed_deferral, __iced_deferrals, __iced_k; __iced_k = __iced_k_noop; ___iced_passed_deferral = iced.findDeferral(arguments); input = _arg.input, key = _arg.key, salt = _arg.salt, progress_hook = _arg.progress_hook; (function(_this) { return (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.sign" }); _this._check_scrubbed(key, "HMAC", cb, __iced_deferrals.defer({ lineno: 210 })); __iced_deferrals._fulfill(); }); })(this)((function(_this) { return function() { input = (new WordArray(_this.version.header)).concat(salt).concat(input); combine_klasses = _this.version.hmac_hashes; (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.sign" }); Concat.bulk_sign({ key: key, input: input, progress_hook: progress_hook, combine_klasses: combine_klasses }, __iced_deferrals.defer({ assign_fn: (function() { return function() { return out = arguments[0]; }; })(), lineno: 213 })); __iced_deferrals._fulfill(); })(function() { input.scrub(); return cb(null, out); }); }; })(this)); }; Base.prototype.run_salsa20 = function(_arg, cb) { var args, ct, input, iv, key, output_iv, progress_hook, ___iced_passed_deferral, __iced_deferrals, __iced_k; __iced_k = __iced_k_noop; ___iced_passed_deferral = iced.findDeferral(arguments); input = _arg.input, key = _arg.key, iv = _arg.iv, output_iv = _arg.output_iv, progress_hook = _arg.progress_hook; (function(_this) { return (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.run_salsa20" }); _this._check_scrubbed(key, "Salsa20", cb, __iced_deferrals.defer({ lineno: 229 })); __iced_deferrals._fulfill(); }); })(this)((function(_this) { return function() { args = { input: input, progress_hook: progress_hook, key: key, iv: iv }; if (_this.version.xsalsa20_rev) { args.key = key.clone().endian_reverse(); args.iv = iv.clone().endian_reverse(); } (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.run_salsa20" }); salsa20.bulk_encrypt(args, __iced_deferrals.defer({ assign_fn: (function() { return function() { return ct = arguments[0]; }; })(), lineno: 241 })); __iced_deferrals._fulfill(); })(function() { if (output_iv) { ct = iv.clone().concat(ct); } if (_this.version.xsalsa20_rev) { args.key.scrub(); args.iv.scrub(); } return cb(null, ct); }); }; })(this)); }; Base.prototype.run_twofish = function(_arg, cb) { var block_cipher, ct, input, iv, key, progress_hook, ___iced_passed_deferral, __iced_deferrals, __iced_k; __iced_k = __iced_k_noop; ___iced_passed_deferral = iced.findDeferral(arguments); input = _arg.input, key = _arg.key, iv = _arg.iv, progress_hook = _arg.progress_hook; (function(_this) { return (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.run_twofish" }); _this._check_scrubbed(key, "TwoFish", cb, __iced_deferrals.defer({ lineno: 264 })); __iced_deferrals._fulfill(); }); })(this)((function(_this) { return function() { block_cipher = new TwoFish(key); (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.run_twofish" }); ctr.bulk_encrypt({ block_cipher: block_cipher, iv: iv, input: input, progress_hook: progress_hook, what: "twofish" }, __iced_deferrals.defer({ assign_fn: (function() { return function() { return ct = arguments[0]; }; })(), lineno: 266 })); __iced_deferrals._fulfill(); })(function() { block_cipher.scrub(); return cb(null, iv.clone().concat(ct)); }); }; })(this)); }; Base.prototype.run_aes = function(_arg, cb) { var block_cipher, ct, input, iv, key, progress_hook, ___iced_passed_deferral, __iced_deferrals, __iced_k; __iced_k = __iced_k_noop; ___iced_passed_deferral = iced.findDeferral(arguments); input = _arg.input, key = _arg.key, iv = _arg.iv, progress_hook = _arg.progress_hook; (function(_this) { return (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.run_aes" }); _this._check_scrubbed(key, "AES", cb, __iced_deferrals.defer({ lineno: 281 })); __iced_deferrals._fulfill(); }); })(this)((function(_this) { return function() { block_cipher = new AES(key); (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Base.run_aes" }); ctr.bulk_encrypt({ block_cipher: block_cipher, iv: iv, input: input, progress_hook: progress_hook, what: "aes" }, __iced_deferrals.defer({ assign_fn: (function() { return function() { return ct = arguments[0]; }; })(), lineno: 283 })); __iced_deferrals._fulfill(); })(function() { block_cipher.scrub(); return cb(null, iv.clone().concat(ct)); }); }; })(this)); }; Base.prototype.scrub = function() { var algo, key, key_ring, salt, _ref1; if (this.key != null) { this.key.scrub(); } if (this.derived_keys != null) { _ref1 = this.derived_keys; for (salt in _ref1) { key_ring = _ref1[salt]; for (algo in key_ring) { key = key_ring[algo]; if (algo !== 'extra') { key.scrub(); } } } } this.derived_keys = {}; if (this.salt != null) { this.salt.scrub(); } this.salt = null; return this.key = null; }; Base.prototype.clone_derived_keys = function() { var algo, key, key_ring, ret, salt, _ref1; ret = null; if (this.derived_keys != null) { ret = {}; _ref1 = this.derived_keys; for (salt in _ref1) { key_ring = _ref1[salt]; ret[salt] = {}; for (algo in key_ring) { key = key_ring[algo]; ret[salt][algo] = algo === 'extra' ? key : key.clone(); } } } return ret; }; return Base; })(); Encryptor = (function(_super) { __extends(Encryptor, _super); function Encryptor(_arg) { var key, rng, version; key = _arg.key, rng = _arg.rng, version = _arg.version; Encryptor.__super__.constructor.call(this, { key: key, version: version }); this.rng = rng || prng.generate; } Encryptor.prototype.pick_random_ivs = function(_arg, cb) { var iv_lens, ivs, k, progress_hook, v, ___iced_passed_deferral, __iced_deferrals, __iced_k; __iced_k = __iced_k_noop; ___iced_passed_deferral = iced.findDeferral(arguments); progress_hook = _arg.progress_hook; iv_lens = []; iv_lens.push(['aes', AES.ivSize]); if (this.version.use_twofish) { iv_lens.push(['twofish', TwoFish.ivSize]); } iv_lens.push(['salsa20', salsa20.Salsa20.ivSize]); ivs = {}; (function(_this) { return (function(__iced_k) { var _i, _len, _ref1, _results, _while; _ref1 = iv_lens; _len = _ref1.length; _i = 0; _while = function(__iced_k) { var _break, _continue, _next, _ref2; _break = __iced_k; _continue = function() { return iced.trampoline(function() { ++_i; return _while(__iced_k); }); }; _next = _continue; if (!(_i < _len)) { return _break(); } else { _ref2 = _ref1[_i], k = _ref2[0], v = _ref2[1]; (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Encryptor.pick_random_ivs" }); _this.rng(v, __iced_deferrals.defer({ assign_fn: (function(__slot_1, __slot_2) { return function() { return __slot_1[__slot_2] = arguments[0]; }; })(ivs, k), lineno: 407 })); __iced_deferrals._fulfill(); })(_next); } }; _while(__iced_k); }); })(this)((function(_this) { return function() { return cb(ivs); }; })(this)); }; Encryptor.prototype.resalt = function(_arg, cb) { var err, extra_keymaterial, progress_hook, salt, ___iced_passed_deferral, __iced_deferrals, __iced_k; __iced_k = __iced_k_noop; ___iced_passed_deferral = iced.findDeferral(arguments); salt = _arg.salt, extra_keymaterial = _arg.extra_keymaterial, progress_hook = _arg.progress_hook; err = null; (function(_this) { return (function(__iced_k) { if (salt == null) { (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Encryptor.resalt" }); _this.rng(_this.version.salt_size, __iced_deferrals.defer({ assign_fn: (function(__slot_1) { return function() { return __slot_1.salt = arguments[0]; }; })(_this), lineno: 423 })); __iced_deferrals._fulfill(); })(__iced_k); } else { return __iced_k(salt.length !== _this.version.salt_size ? err = new Error("Need a salt of exactly " + _this.version.salt_size + " bytes (got " + salt.length + ")") : _this.salt = WordArray.alloc(salt)); } }); })(this)((function(_this) { return function() { (function(__iced_k) { if (err == null) { (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Encryptor.resalt" }); _this.kdf({ extra_keymaterial: extra_keymaterial, progress_hook: progress_hook, salt: _this.salt }, __iced_deferrals.defer({ assign_fn: (function(__slot_1) { return function() { err = arguments[0]; return __slot_1.keys = arguments[1]; }; })(_this), lineno: 429 })); __iced_deferrals._fulfill(); })(__iced_k); } else { return __iced_k(); } })(function() { return cb(err, _this.keys); }); }; })(this)); }; Encryptor.prototype.run = function(_arg, cb) { var ct3, data, esc, extra_keymaterial, ivs, mid, progress_hook, pt, ret, salt, sig, ___iced_passed_deferral, __iced_deferrals, __iced_k; __iced_k = __iced_k_noop; ___iced_passed_deferral = iced.findDeferral(arguments); data = _arg.data, salt = _arg.salt, extra_keymaterial = _arg.extra_keymaterial, progress_hook = _arg.progress_hook; esc = make_esc(cb, "Encryptor::run"); (function(_this) { return (function(__iced_k) { if ((salt != null) || (_this.salt == null)) { (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Encryptor.run" }); _this.resalt({ salt: salt, extra_keymaterial: extra_keymaterial, progress_hook: progress_hook }, esc(__iced_deferrals.defer({ lineno: 460 }))); __iced_deferrals._fulfill(); })(__iced_k); } else { return __iced_k(); } }); })(this)((function(_this) { return function() { (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Encryptor.run" }); _this.pick_random_ivs({ progress_hook: progress_hook }, __iced_deferrals.defer({ assign_fn: (function() { return function() { return ivs = arguments[0]; }; })(), lineno: 461 })); __iced_deferrals._fulfill(); })(function() { pt = WordArray.from_buffer(data); (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Encryptor.run" }); _this.run_salsa20({ input: pt, key: _this.keys.salsa20, progress_hook: progress_hook, iv: ivs.salsa20, output_iv: true }, esc(__iced_deferrals.defer({ assign_fn: (function() { return function() { return mid = arguments[0]; }; })(), lineno: 463 }))); __iced_deferrals._fulfill(); })(function() { (function(__iced_k) { if (_this.version.use_twofish) { (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Encryptor.run" }); _this.run_twofish({ input: mid, key: _this.keys.twofish, progress_hook: progress_hook, iv: ivs.twofish }, esc(__iced_deferrals.defer({ assign_fn: (function() { return function() { return mid = arguments[0]; }; })(), lineno: 465 }))); __iced_deferrals._fulfill(); })(__iced_k); } else { return __iced_k(); } })(function() { (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Encryptor.run" }); _this.run_aes({ input: mid, key: _this.keys.aes, progress_hook: progress_hook, iv: ivs.aes }, esc(__iced_deferrals.defer({ assign_fn: (function() { return function() { return ct3 = arguments[0]; }; })(), lineno: 466 }))); __iced_deferrals._fulfill(); })(function() { (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced", funcname: "Encryptor.run" }); _this.sign({ input: ct3, key: _this.keys.hmac, progress_hook: progress_hook, salt: _this.salt }, esc(__iced_deferrals.defer({ assign_fn: (function() { return function() { return sig = arguments[0]; }; })(), lineno: 467 }))); __iced_deferrals._fulfill(); })(function() { ret = (new WordArray(_this.version.header)).concat(_this.salt).concat(sig).concat(ct3).to_buffer(); util.scrub_buffer(data); return cb(null, ret); }); }); }); }); }); }; })(this)); }; Encryptor.prototype.clone = function() { var ret, _ref1, _ref2; ret = new Encryptor({ key: (_ref1 = this.key) != null ? _ref1.to_buffer() : void 0, rng: this.rng, version: (_ref2 = this.version) != null ? _ref2.version : void 0 }); ret.derived_keys = this.clone_derived_keys(); return ret; }; return Encryptor; })(Base); encrypt = function(_arg, cb) { var data, enc, err, key, progress_hook, ret, rng, version, ___iced_passed_deferral, __iced_deferrals, __iced_k; __iced_k = __iced_k_noop; ___iced_passed_deferral = iced.findDeferral(arguments); key = _arg.key, data = _arg.data, rng = _arg.rng, progress_hook = _arg.progress_hook, version = _arg.version; enc = new Encryptor({ key: key, rng: rng, version: version }); (function(_this) { return (function(__iced_k) { __iced_deferrals = new iced.Deferrals(__iced_k, { parent: ___iced_passed_deferral, filename: "/Users/max/src/keybase/triplesec/src/enc.iced" }); enc.run({ data: data, progress_hook: progress_hook }, __iced_deferrals.defer({ assign_fn: (function() { return function() { err = arguments[0]; return ret = arguments[1]; }; })(), lineno: 506 })); __iced_deferrals._fulfill(); }); })(this)((function(_this) { return function() { enc.scrub(); return cb(err, ret); }; })(this)); }; exports.V = V; exports.encrypt = encrypt; exports.Base = Base; exports.Encryptor = Encryptor; }).call(this);