libves 2.3.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,47 +1,46 @@
1
- ## libVES
1
+ # libVES
2
2
 
3
+ ### Browser PIN-based e2e encryption at-rest
4
+ ## Simple * Safe * Secure
3
5
 
4
- Simple, safe and secure e2e encryption for data at-rest.
5
6
 
7
+ [VESvault.com](https://vesvault.com) | [VES.host](https://ves.host) | [VESlocker.com](https://veslocker.com) | [demo.VES.world](https://demo.ves.world)
6
8
 
7
- https://VESvault.com
8
9
 
9
- https://VES.host
10
+ #### Instantiate libVES
10
11
 
12
+ var VES = new libVES({domain: 'x-myapp'});
11
13
 
12
- ; Instantiate libVES
13
14
 
14
- var VES = new libVES({domain: 'x-myapp'});
15
+ #### Authorize with VES in the same browser window
15
16
 
17
+ VES.flow(true).then(....)
16
18
 
17
- ; Authorize with VES in the same browser window
18
19
 
19
- VES.flow(true).then(....)
20
+ #### Or, authorize with VES via a popup window
20
21
 
22
+ VES.delegate().then(....)
21
23
 
22
- ; Or, authorize in a popup window
23
24
 
24
- VES.delegate().then(....)
25
+ #### Store an e2e encrypted value
25
26
 
27
+ VES.putValue('item-id', 'value')
26
28
 
27
- ; Store an e2e encrypted value
28
29
 
29
- VES.putValue('item-id', 'value')
30
+ #### Store a value and e2e share with other VES accounts
30
31
 
32
+ VES.putValue('item-id', 'value', [
33
+ {externalId: 'me@acme.com'},
34
+ {externalId: 'user1@acme.com'},
35
+ {externalId: 'user2@acme.com'}
36
+ ])
31
37
 
32
- ; Store a value and e2e share with other VES accounts
33
38
 
34
- VES.putValue('item-id', 'value', [{externalId: 'me@acme.com'}, {externalId: 'user1@acme.com'}, {externalId: 'user2@acme.com'}])
39
+ #### Retrieve a previously stored value
35
40
 
41
+ VES.getValue('item-id').then(function(value) { .... })
36
42
 
37
- ; Retrieve a previously stored value
38
43
 
39
- VES.getValue('item-id').then(function(value) { .... })
40
-
41
-
42
- See https://demo.ves.world
43
-
44
-
45
- Full API Docs:
44
+ ### Full API Docs:
46
45
 
47
46
  https://ves.host/docs/libVES
package/libVES.node.js CHANGED
@@ -27,7 +27,7 @@
27
27
  *
28
28
  * @title libVES
29
29
  * @dev A JavaScript end-to-end encryption interface to VESvault REST API
30
- * @version 2.03
30
+ * @version 2.06
31
31
  *
32
32
  * @dev Official source code: https://github.com/vesvault/libVES
33
33
  *
@@ -429,7 +429,14 @@ libVES.prototype = {
429
429
  if (self.e2e && self.e2e.length) usr.e2e = self.getVESkeyE2E(veskey, usr);
430
430
  key.setField('vaultItems', veskey.then(function(v) {
431
431
  var vi = new libVES.VaultItem({type: 'password'}, self);
432
- return Promise.all(self.type == 'secondary' ? [self.me(), self.getVaultKey()] : [self.me()]).then(function(sh) {
432
+ return usr.getActiveVaultKeys().then(function() {
433
+ return [self.me(), self.getVaultKey(), usr];
434
+ }).catch(function(e) {
435
+ if (e.code != 'NotFound') throw e;
436
+ return self.type == 'secondary' ? [self.me(), self.getVaultKey()] : [self.me()];
437
+ }).then(function(sh) {
438
+ return Promise.all(sh);
439
+ }).then(function(sh) {
433
440
  return vi.shareWith(sh, v, false).then(function() {
434
441
  return [vi];
435
442
  });
@@ -1178,7 +1185,17 @@ libVES.Util = {
1178
1185
  }
1179
1186
  },
1180
1187
  PKCS8: {
1181
- encode: function(key,optns) {
1188
+ encode: function(key, optns) {
1189
+ return crypto.subtle.exportKey('pkcs8',key).catch(function(e) {
1190
+ console.log('PKCS8 failed, trying JWK...');
1191
+ return crypto.subtle.exportKey('jwk', key).then(function(jwk) {
1192
+ return libVES.Util.PKCS8.fromJWK(jwk);
1193
+ });
1194
+ }).then(function(pkcs8) {
1195
+ return libVES.Util.PKCS8.encode8(pkcs8, optns);
1196
+ });
1197
+ },
1198
+ encode8: function(pkcs8, optns) {
1182
1199
  var ops = {};
1183
1200
  for (var k in optns) ops[k] = optns[k];
1184
1201
  if (!ops.members) ops.members = [
@@ -1187,24 +1204,17 @@ libVES.Util = {
1187
1204
  ];
1188
1205
  return Promise.all(ops.members).then(function(ms) {
1189
1206
  ops.members = ms;
1190
- return crypto.subtle.exportKey('pkcs8',key).catch(function(e) {
1191
- console.log('PKCS8 failed, trying JWK...');
1192
- return crypto.subtle.exportKey('jwk', key).then(function(jwk) {
1193
- return libVES.Util.PKCS8.fromJWK(jwk);
1194
- });
1195
- }).then(function(der) {
1196
- ops.content = der;
1197
- var rec = [];
1198
- if (ops.password) return libVES.Util.PKCS5.export(function(call,optns) {
1199
- rec[1] = optns.content;
1200
- return Promise.resolve();
1201
- },ops).then(function(data) {
1202
- rec[0] = data;
1203
- return libVES.Util.PEM.encode(libVES.Util.ASN1.encode([rec]),'ENCRYPTED PRIVATE KEY');
1204
- });
1205
- else if (ops.opentext) return libVES.Util.PEM.encode(der,'PRIVATE KEY');
1206
- else throw new libVES.Error('Internal','No password for key export (opentext=true to export without password?)');
1207
+ ops.content = pkcs8;
1208
+ var rec = [];
1209
+ if (ops.password) return libVES.Util.PKCS5.export(function(call,optns) {
1210
+ rec[1] = optns.content;
1211
+ return Promise.resolve();
1212
+ },ops).then(function(data) {
1213
+ rec[0] = data;
1214
+ return libVES.Util.PEM.encode(libVES.Util.ASN1.encode([rec]),'ENCRYPTED PRIVATE KEY');
1207
1215
  });
1216
+ else if (ops.opentext) return libVES.Util.PEM.encode(pkcs8,'PRIVATE KEY');
1217
+ else throw new libVES.Error('Internal','No password for key export (opentext=true to export without password?)');
1208
1218
  });
1209
1219
  },
1210
1220
  fromJWK: function(jwk) {
@@ -1399,6 +1409,7 @@ libVES.Util.OID['1.2.840.113549.2.7'] = libVES.getModuleFunc(libVES, ['Util', 'H
1399
1409
  libVES.Util.OID['1.2.840.113549.2.9'] = libVES.getModuleFunc(libVES, ['Util', 'Hash', 'SHA256']);
1400
1410
  libVES.Util.OID['1.2.840.113549.2.10'] = libVES.getModuleFunc(libVES, ['Util', 'Hash', 'SHA384']);
1401
1411
  libVES.Util.OID['1.2.840.113549.2.11'] = libVES.getModuleFunc(libVES, ['Util', 'Hash', 'SHA512']);
1412
+ libVES.Util.OID['1.3.6.1.4.1.53675.3.5'] = libVES.getModuleFunc(libVES, ['Algo', 'OQS', 'Util']);
1402
1413
 
1403
1414
  libVES.Math = {
1404
1415
  pad: function(a,n) {
@@ -2107,7 +2118,7 @@ libVES.VaultKey.prototype = new libVES.Object({
2107
2118
 
2108
2119
  libVES.VaultItem.prototype = new libVES.Object({
2109
2120
  apiUri: 'vaultItems',
2110
- fieldList: {id: true},
2121
+ fieldList: {id: true, deleted: true, file: true},
2111
2122
  fieldClass: {vaultKey: libVES.VaultKey, file: libVES.File},
2112
2123
  fieldSets: [{type: true, meta: true},{vaultEntries: {id: true, encData: true, vaultKey: {id: true, type: true, user: {id: true}, algo: true, externals: {id: true}}}},{vaultKey: true, file: true}],
2113
2124
  defaultCipher: 'AES256GCM',
@@ -2164,6 +2175,9 @@ libVES.VaultItem.prototype = new libVES.Object({
2164
2175
  getFile: function() {
2165
2176
  return this.getField('file');
2166
2177
  },
2178
+ getDeleted: function() {
2179
+ return this.getField('deleted');
2180
+ },
2167
2181
  parse: function(buf) {
2168
2182
  var self = this;
2169
2183
  return this.getType().then(function(type) {
@@ -2332,7 +2346,7 @@ libVES.VaultItem.Type.password = libVES.VaultItem.Type.string;
2332
2346
 
2333
2347
  libVES.File.prototype = new libVES.Object({
2334
2348
  apiUri: 'files',
2335
- fieldList: {id: true},
2349
+ fieldList: {id: true, externals: true},
2336
2350
  fieldClass: {externals: libVES.External, creator: libVES.User},
2337
2351
  getExternals: function() {
2338
2352
  return this.getField('externals');
@@ -3660,4 +3674,184 @@ libVES.Auth.prototype.verify = function(token, auth) {
3660
3674
  });
3661
3675
  };
3662
3676
 
3677
+
3678
+ libVES.Algo.OQS = {
3679
+ tag: 'OQS',
3680
+ wasm: function() {
3681
+ if (!this.wasmP) this.wasmP = new Promise(function(resolve, reject) {
3682
+ if (typeof(WasmOQS) == 'function') return resolve();
3683
+ var sc = document.createElement('script');
3684
+ sc.async = false;
3685
+ sc.src = WasmOQSinit.baseUrl + 'WasmOQS.js';
3686
+ sc.onload = resolve;
3687
+ sc.onerror = reject;
3688
+ document.getElementsByTagName('head')[0].appendChild(sc);
3689
+ }).then(function() {
3690
+ return WasmOQS(WasmOQSinit);
3691
+ });
3692
+ return this.wasmP;
3693
+ },
3694
+ decrypt: function(k,buf) {
3695
+ return this.wasm().then(function(wasm) {
3696
+ var b = new Uint8Array(buf);
3697
+ if (b.byteLength <= k.ctextlen) throw new libVES.Error('InvalidValue', 'Ciphertext is too short');
3698
+ var secret = wasm.decaps(k, b.slice(0, k.ctextlen));
3699
+ if (!secret) throw new libVES.Error('InvalidValue', 'OQS decryption error');
3700
+ return libVES.Algo.OQS.cipher(secret).then(function(ci) {
3701
+ return ci.decrypt(b.slice(k.ctextlen), true).catch(function(e) {
3702
+ if (e instanceof libVES.Error) throw e;
3703
+ throw new libVES.Error('InvalidValue', 'Error decrypting ECIES payload: Invalid ciphertext?',{error:e});
3704
+ });
3705
+ }).catch(function(e) {
3706
+ if (e instanceof libVES.Error) throw e;
3707
+ throw new libVES.Error('InvalidValue', 'Error negotiating ECIES cipher key: Invalid ciphertext?',{error:e});
3708
+ });
3709
+ })
3710
+ },
3711
+ encrypt: function(k, buf) {
3712
+ return this.wasm().then(function(wasm) {
3713
+ var ctext = wasm.encaps(k);
3714
+ if (!ctext) throw new libVES.Error('InvalidValue', 'Error generating OQS secret');
3715
+ return libVES.Algo.OQS.cipher(wasm.decaps(k)).then(function(ci) {
3716
+ return ci.encrypt(buf, true).then(function(ctext2) {
3717
+ var buf = new Uint8Array(ctext.byteLength + ctext2.byteLength);
3718
+ buf.set(new Uint8Array(ctext),0);
3719
+ buf.set(new Uint8Array(ctext2),ctext.byteLength);
3720
+ return buf;
3721
+ });
3722
+ }).catch(function(e) {
3723
+ if (e instanceof libVES.Error) throw e;
3724
+ throw new libVES.Error('InvalidValue', 'Error generating ECIES cipher',{error:e});
3725
+ });
3726
+ });
3727
+ },
3728
+ cipher: function(secret) {
3729
+ return libVES.getModule(libVES.Cipher,'AES256GCMp').then(function(m) {
3730
+ return crypto.subtle.digest({name:'SHA-384'}, secret).then(function(buf) {
3731
+ return new m(new Uint8Array(buf).slice(0, m.prototype.keySize + m.prototype.ivSize));
3732
+ });
3733
+ });
3734
+ },
3735
+ import: function(data,optns) {
3736
+ return libVES.Util.PEM.import(data,optns);
3737
+ },
3738
+ export: function(data, optns) {
3739
+ if (!data || !data.ptr) throw new libVES.Error('Internal', "Unknown type of key object");
3740
+ var pub = new Uint8Array(data.pub.byteLength + 1);
3741
+ pub[0] = 0;
3742
+ pub.set(new Uint8Array(data.pub), 1);
3743
+ pub.ASN1type = 3;
3744
+ var oid = [new libVES.Util.OID(libVES.Algo.OQS.OID), libVES.Util.StringToByteArray(data.algo)];
3745
+ if (data.priv) {
3746
+ pub = libVES.Util.ASN1.encode([pub]);
3747
+ pub.ASN1type = 0xa1;
3748
+ var buf = libVES.Util.ASN1.encode([[1, data.priv, pub]]);
3749
+ var pkcs8 = libVES.Util.ASN1.encode([[0, oid, buf]]);
3750
+ return libVES.Util.PKCS8.encode8(pkcs8, optns);
3751
+ }
3752
+ return libVES.Util.PEM.encode(libVES.Util.ASN1.encode([[oid, pub]]), 'PUBLIC KEY');
3753
+ },
3754
+ generate: function(optns) {
3755
+ var algo = optns ? optns.algo : null;
3756
+ if (!algo) algo = this.defaultAlgo;
3757
+ return this.wasm().then(function(wasm) {
3758
+ var k = wasm.init(algo, true);
3759
+ if (!k) throw new libVES.Error('InvalidValue', 'OQS key init failed');
3760
+ if (!wasm.generate(k)) throw new libVES.Error('Internal', 'OQS generate failed');
3761
+ var pub = {};
3762
+ for (var i in k) if (i != 'priv') pub[i] = k[i];
3763
+ return {privateKey: k, publicKey: pub};
3764
+ });
3765
+ },
3766
+ Util: {
3767
+ import: function(args,chain,optns) {
3768
+ var algo = libVES.Util.ByteArrayToString(args);
3769
+ return chain('container').then(function(der) {
3770
+ var asn = libVES.Util.ASN1.decode(der)[0];
3771
+ var pkey = null;
3772
+ var pub = null;
3773
+ if (typeof(asn[0]) == 'number') {
3774
+ var asn2 = libVES.Util.ASN1.decode(asn[2])[0];
3775
+ pkey = asn2[1];
3776
+ pub = libVES.Util.ASN1.decode(asn2[2])[0];
3777
+ } else pkey = asn[1];
3778
+ return libVES.Algo.OQS.wasm().then(function(wasm) {
3779
+ var k = wasm.init(algo, !!pub);
3780
+ if (!k) throw new libVES.Error('InvalidValue', 'OQS key init failed (bad algo?)');
3781
+ var s = function(dst, src, dif) {
3782
+ if (!dst || !src || dst.byteLength != src.byteLength - dif) throw new libVES.Error('InvalidValue', 'Incorrect OQS key size');
3783
+ dst.set(src.slice(dif), 0);
3784
+ };
3785
+ if (pub) {
3786
+ s(k.priv, pkey, 0);
3787
+ s(k.pub, pub, 1);
3788
+ } else s(k.pub, pkey, 1);
3789
+ return k;
3790
+ });
3791
+ });
3792
+ }
3793
+ },
3794
+ OID: '1.3.6.1.4.1.53675.3.5',
3795
+ defaultAlgo: 'Kyber768'
3796
+ };
3797
+
3798
+ var WasmOQSinit = {
3799
+ init: function(algo, priv) {
3800
+ var a = new Uint8Array(libVES.Util.StringToByteArray(algo));
3801
+ var arg1 = new Uint8Array(this.asm.memory.buffer, 16, 48);
3802
+ arg1.set(a);
3803
+ arg1.set([0], a.byteLength);
3804
+ var ptr = this._WasmOQS_new(arg1.byteOffset, priv);
3805
+ if (!ptr) return null;
3806
+ var key = { ptr: ptr };
3807
+ var priv = this._WasmOQS_priv(ptr);
3808
+ if (priv) key.priv = new Uint8Array(this.asm.memory.buffer, priv, this._WasmOQS_privlen(ptr));
3809
+ key.pub = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_pub(ptr), this._WasmOQS_publen(ptr));
3810
+ key.secretlen = this._WasmOQS_decaps(key.ptr, null, null);
3811
+ key.ctextlen = this._WasmOQS_encaps(key.ptr, null, null);
3812
+ key.algo = algo;
3813
+ return key;
3814
+ },
3815
+ generate: function(key) {
3816
+ return this._WasmOQS_generate(key.ptr) >= 0;
3817
+ },
3818
+ encaps: function(key) {
3819
+ var arg1 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_secretbuf, this._WasmOQS_decaps(key.ptr, null, null));
3820
+ var arg2 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_ctextbuf, this._WasmOQS_encaps(key.ptr, null, null));
3821
+ if (this._WasmOQS_encaps(key.ptr, arg2.byteOffset, arg1.byteOffset) <= 0) return null;
3822
+ key.secret = new Uint8Array(arg1.byteLength);
3823
+ key.secret.set(arg1);
3824
+ var ctext = new Uint8Array(arg2.byteLength);
3825
+ ctext.set(arg2);
3826
+ return ctext;
3827
+ },
3828
+ decaps: function(key, ctext) {
3829
+ if (!ctext) return key.secret;
3830
+ if (ctext.byteLength != this._WasmOQS_encaps(key.ptr, null, null)) return null;
3831
+ var arg1 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_secretbuf, this._WasmOQS_decaps(key.ptr, null, null));
3832
+ var arg2 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_ctextbuf, ctext.byteLength);
3833
+ arg2.set(ctext);
3834
+ if (this._WasmOQS_decaps(key.ptr, arg1.byteOffset, arg2.byteOffset) <= 0) return null;
3835
+ key.secret = new Uint8Array(arg1.byteLength);
3836
+ key.secret.set(arg1);
3837
+ return key.secret;
3838
+ },
3839
+ free: function(key) {
3840
+ this._WasmOQS_free(key.ptr);
3841
+ },
3842
+ test: function(algo) {
3843
+ var k = this.init(algo, 1);
3844
+ this.generate(k);
3845
+ console.log(k);
3846
+ var ctext = this.encaps(k);
3847
+ console.log(k.secret, ctext);
3848
+ var secret = this.decaps(k);
3849
+ console.log(secret);
3850
+ },
3851
+ locateFile: function(file) {
3852
+ return this.baseUrl + file;
3853
+ },
3854
+ baseUrl: 'https://ves.host/pub/'
3855
+ };
3856
+
3663
3857
  module.exports = libVES;
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libves",
3
- "version": "2.3.0",
3
+ "version": "2.6.0",
4
4
  "description": "Simple, safe and secure end-to-end encryption at-rest",
5
5
  "main": "libVES.node.js",
6
6
  "scripts": {
package/libves-2.3.0.tgz DELETED
Binary file