libves 2.3.1 → 2.16.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/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.16
31
31
  *
32
32
  * @dev Official source code: https://github.com/vesvault/libVES
33
33
  *
@@ -54,17 +54,20 @@ if (typeof(libVES) != 'function') function libVES(optns) {
54
54
  }
55
55
 
56
56
  libVES.prototype = {
57
+ constructor: libVES,
57
58
  apiUrl: 'https://api.ves.host/v1/',
59
+ pollUrl: 'https://poll.ves.host/v1/',
58
60
  wwwUrl: 'https://www.vesvault.com/',
59
61
  keyAlgo: 'ECDH',
62
+ keyOptions: {namedCurve: 'P-521'},
60
63
  textCipher: 'AES256GCMp',
61
64
  defaultHash: 'SHA256',
62
-
65
+ propagators: [],
63
66
  request: function(method,uri,body,optns) {
64
67
  if (!optns) optns = {};
65
68
  return new Promise(function(resolve,reject) {
66
69
  var xhr = new XMLHttpRequest();
67
- xhr.open(method,this.apiUrl + uri);
70
+ xhr.open(method, (uri.match(/^https\:/) ? uri : this.apiUrl + uri));
68
71
  if (optns.abortFn) optns.abortFn(function() {
69
72
  return xhr.abort();
70
73
  });
@@ -183,7 +186,7 @@ libVES.prototype = {
183
186
  return flow.setValue(undefined).then(function() {
184
187
  return flow.addToken(url).then(function(url) {
185
188
  document.location.replace(url);
186
- throw {code: 'Redirect', message: 'Starting VES Authorization...'};
189
+ throw new libVES.Error('Redirect', 'Starting VES Authorization...');
187
190
  });
188
191
  });
189
192
  });
@@ -294,13 +297,16 @@ libVES.prototype = {
294
297
  var self = this;
295
298
  return this.getVaultKey().then(function(k) {
296
299
  return k.getId().then(function(kid) {
297
- return k.getVaultEntries().then(function(ves) {
300
+ return k.getVaultEntries({type: true, deleted: true, file: {creator: true, externals: true}, vaultKey: {type: true, user: true}}).then(function(ves) {
298
301
  var vis = {};
299
302
  var vlst = [];
300
303
  for (var i = 0; i < ves.length; i++) {
301
304
  var viid = ves[i].vaultItem.id;
302
305
  if (!vis[viid]) {
303
- var vi = vis[viid] = self.getItem(ves[i].vaultItem);
306
+ var vi = ves[i].vaultItem;
307
+ if (!vi.file) vi.file = undefined;
308
+ if (!vi.vaultKey) vi.vaultKey = undefined;
309
+ vi = vis[viid] = self.getItem(vi);
304
310
  vlst.push(vi);
305
311
  vi.vaultEntryByKey[kid] = ves[i];
306
312
  }
@@ -356,7 +362,7 @@ libVES.prototype = {
356
362
  },
357
363
  vaultRefToUser: function(ext) {
358
364
  var email = ext.externalId ? ext.externalId.replace(/\!.*/, '') : '';
359
- if (!email.match(/\@/)) throw {code: 'NotFound', message: 'externalId is not an email for non-existing vault'};
365
+ if (!email.match(/\@/)) throw new libVES.Error('NotFound', 'externalId is not an email for non-existing vault');
360
366
  return new libVES.User({email: email}, self);
361
367
  }
362
368
  };
@@ -426,10 +432,18 @@ libVES.prototype = {
426
432
  var key = new libVES.VaultKey({type: 'temp', algo: this.keyAlgo, user: usr}, self);
427
433
  var veskey = this.generateVESkey(usr);
428
434
  return key.generate(veskey, optns).then(function(k) {
429
- if (self.e2e && self.e2e.length) usr.e2e = self.getVESkeyE2E(veskey, usr);
430
435
  key.setField('vaultItems', veskey.then(function(v) {
431
436
  var vi = new libVES.VaultItem({type: 'password'}, self);
432
- return Promise.all(self.type == 'secondary' ? [self.me(), self.getVaultKey()] : [self.me()]).then(function(sh) {
437
+ return usr.getActiveVaultKeys().then(function() {
438
+ return [self.me(), self.getVaultKey(), usr];
439
+ }).catch(function(e) {
440
+ if (e.code != 'NotFound') throw e;
441
+ var sh = self.type == 'secondary' ? [self.me(), self.getVaultKey()] : [self.me()];
442
+ if (self.propagators) for (var i = 0; i < self.propagators.length; i++) sh.push(self.propagators[i]);
443
+ return sh;
444
+ }).then(function(sh) {
445
+ return Promise.all(sh);
446
+ }).then(function(sh) {
433
447
  return vi.shareWith(sh, v, false).then(function() {
434
448
  return [vi];
435
449
  });
@@ -444,18 +458,6 @@ libVES.prototype = {
444
458
  crypto.getRandomValues(buf);
445
459
  return Promise.resolve(libVES.Util.ByteArrayToB64(buf));
446
460
  },
447
- getVESkeyE2E: function(veskey,usr) {
448
- var self = this;
449
- return veskey.then(function(v) {
450
- return libVES.getModule(libVES.E2E,['Dialog','TempKey']).then(function(cls) {
451
- return new cls({
452
- user: usr,
453
- e2e: self.e2e,
454
- tempKey: v
455
- });
456
- });
457
- });
458
- },
459
461
  setVESkey: function(veskey,lost,options) {
460
462
  var self = this;
461
463
  return this.me().then(function(me) {
@@ -651,7 +653,7 @@ libVES.prototype = {
651
653
  return Promise.resolve(shareWith || self.getFileItem(fileRef).then(function(vi) {
652
654
  return vi.getShareList();
653
655
  }).catch(function(e) {
654
- return self.usersToKeys([{domain: (fileRef.domain || VES.domain)}]);
656
+ return self.usersToKeys([{domain: VES.domain, externalId: VES.externalId}]);
655
657
  })).then(function(shareWith) {
656
658
  return vaultItem.shareWith(shareWith,value);
657
659
  });
@@ -674,8 +676,8 @@ libVES.prototype = {
674
676
  });
675
677
  },
676
678
  deleteFile: function(fileRef) {
677
- return this.getFile(fileRef).then(function(file) {
678
- return file.delete();
679
+ return this.getFileItem(fileRef).then(function(item) {
680
+ return item.delete();
679
681
  });
680
682
  },
681
683
  newSecret: function(cls) {
@@ -850,9 +852,11 @@ libVES.prototype = {
850
852
  return vkey.rekey(optns);
851
853
  });
852
854
  else return vkey.getVaultItems().then(function(vis) {
853
- return Promise.all(vis.map(function(vi, i) {
854
- return vi.reshareWith([user]);
855
- }));
855
+ return self.elevateAuth().then(function(optns) {
856
+ return Promise.all(vis.map(function(vi, i) {
857
+ return vi.reshareWith([user], undefined, optns);
858
+ }));
859
+ });
856
860
  });
857
861
  });
858
862
  });
@@ -864,11 +868,27 @@ libVES.prototype = {
864
868
  }
865
869
  });
866
870
  }));
871
+ },
872
+ setKeyAlgo: function(optns) {
873
+ if (typeof(optns) == 'string') {
874
+ this.keyOptions = null;
875
+ return this.keyAlgo = optns;
876
+ }
877
+ var algo = libVES.Algo.fromKeyOptions(optns);
878
+ if (algo) {
879
+ this.keyOptions = optns;
880
+ return this.keyAlgo = algo;
881
+ }
867
882
  }
868
883
  };
869
884
 
870
- libVES.Error = function(code,msg,optns) {
885
+ libVES.Error = function(code, msg, optns) {
886
+ if (libVES.Error[code] && (libVES.Error[code].prototype instanceof libVES.Error)) return new (libVES.Error[code])(msg, optns);
871
887
  this.code = code;
888
+ this.init(msg, optns);
889
+ };
890
+
891
+ libVES.Error.prototype.init = function(msg, optns) {
872
892
  this.message = msg;
873
893
  if (optns) for (var k in optns) this[k] = optns[k];
874
894
  };
@@ -877,6 +897,32 @@ libVES.Error.prototype.toString = function() {
877
897
  return this.message || this.code;
878
898
  };
879
899
 
900
+ libVES.Error.NotFound = function(msg, optns) {
901
+ this.init(msg, optns);
902
+ };
903
+ libVES.Error.NotFound.prototype = new libVES.Error('NotFound');
904
+
905
+ libVES.Error.InvalidValue = function(msg, optns) {
906
+ this.init(msg, optns);
907
+ };
908
+ libVES.Error.InvalidValue.prototype = new libVES.Error('InvalidValue');
909
+
910
+ libVES.Error.InvalidKey = function(msg, optns) {
911
+ this.init(msg, optns);
912
+ };
913
+ libVES.Error.InvalidKey.prototype = new libVES.Error('InvalidKey');
914
+
915
+ libVES.Error.Redirect = function(msg, optns) {
916
+ this.init(msg, optns);
917
+ };
918
+ libVES.Error.Redirect.prototype = new libVES.Error('Redirect');
919
+
920
+ libVES.Error.Internal = function(msg, optns) {
921
+ this.init(msg, optns);
922
+ };
923
+ libVES.Error.Internal.prototype = new libVES.Error('Internal');
924
+
925
+
880
926
  libVES.getModule = function(sectn,mods) {
881
927
  var mod;
882
928
  if (mods instanceof Array) mod = mods[0];
@@ -897,6 +943,9 @@ libVES.getModuleFunc = function(sectn,mod,then) {
897
943
  libVES.loadModule = function(sectn,mod) {
898
944
  return Promise.reject(new libVES.Error('Internal',"Cannot load " + sectn + '.' + mod));
899
945
  };
946
+ libVES.maxKeyLen = 48896;
947
+ libVES.maxEncDataLen = 32768;
948
+
900
949
 
901
950
  if (!libVES.Domain) libVES.Domain = {};
902
951
 
@@ -975,6 +1024,16 @@ libVES.Util = {
975
1024
  }
976
1025
  return rs;
977
1026
  },
1027
+ loadWasm: function(src) {
1028
+ return new Promise(function(resolve, reject) {
1029
+ var sc = document.createElement('script');
1030
+ sc.async = false;
1031
+ sc.src = src;
1032
+ sc.onload = resolve;
1033
+ sc.onerror = reject;
1034
+ document.getElementsByTagName('head')[0].appendChild(sc);
1035
+ });
1036
+ },
978
1037
  PEM: {
979
1038
  toDER: function(pem) {
980
1039
  var pp = pem.match(/-----BEGIN.*?-----\s*\r?\n([A-Za-z0-9\/\+\=\s\r\n]*)-----END/);
@@ -1129,6 +1188,43 @@ libVES.Util = {
1129
1188
  this.value = rs.join('.');
1130
1189
  } else this.value = s;
1131
1190
  },
1191
+ Key: {
1192
+ fromDER: function(der, callbk) {
1193
+ var asn = libVES.Util.ASN1.decode(der)[0];
1194
+ if (typeof(asn[0]) == 'number') {
1195
+ var asn2 = libVES.Util.ASN1.decode(asn[2])[0];
1196
+ var pub = libVES.Util.ASN1.decode(asn2[2]);
1197
+ console.log('pub', pub);
1198
+ if (pub) return callbk(pub[0].slice(1), asn2[1], pub[0][0]);
1199
+ else callbk(null, asn2[1]);
1200
+ } else return callbk(asn[1].slice(1), null, asn[1][0]);
1201
+ },
1202
+ pubASN1: function(pub, optns) {
1203
+ var p = new Uint8Array(pub.byteLength + 1);
1204
+ p[0] = optns && optns.pubBits ? optns.pubBits : 0;
1205
+ p.set(new Uint8Array(pub), 1);
1206
+ p.ASN1type = 3;
1207
+ return p;
1208
+ },
1209
+ toPKCS: function(pub, priv, asn1hdr, optns) {
1210
+ if (priv) {
1211
+ var seq = [1, priv];
1212
+ if (pub) {
1213
+ p = libVES.Util.ASN1.encode([libVES.Util.Key.pubASN1(pub, optns)]);
1214
+ p.ASN1type = 0xa1;
1215
+ seq.push(p);
1216
+ }
1217
+ var buf = libVES.Util.ASN1.encode([seq]);
1218
+ return libVES.Util.ASN1.encode([[0, asn1hdr, buf]]);
1219
+ }
1220
+ return libVES.Util.ASN1.encode([[asn1hdr, libVES.Util.Key.pubASN1(pub, optns)]]);
1221
+ },
1222
+ export: function(pub, priv, asn1hdr, optns) {
1223
+ var pkcs = libVES.Util.Key.toPKCS(pub, priv, asn1hdr, optns);
1224
+ if (priv) return libVES.Util.PKCS8.encode8(pkcs, optns);
1225
+ return libVES.Util.PEM.encode(pkcs, 'PUBLIC KEY');
1226
+ }
1227
+ },
1132
1228
  PKCS1: {
1133
1229
  import: function(args,chain,optns) {
1134
1230
  return chain('container',optns).then(function(der) {
@@ -1178,7 +1274,17 @@ libVES.Util = {
1178
1274
  }
1179
1275
  },
1180
1276
  PKCS8: {
1181
- encode: function(key,optns) {
1277
+ encode: function(key, optns) {
1278
+ return crypto.subtle.exportKey('pkcs8',key).catch(function(e) {
1279
+ console.log('PKCS8 failed, trying JWK...');
1280
+ return crypto.subtle.exportKey('jwk', key).then(function(jwk) {
1281
+ return libVES.Util.PKCS8.fromJWK(jwk);
1282
+ });
1283
+ }).then(function(pkcs8) {
1284
+ return libVES.Util.PKCS8.encode8(pkcs8, optns);
1285
+ });
1286
+ },
1287
+ encode8: function(pkcs8, optns) {
1182
1288
  var ops = {};
1183
1289
  for (var k in optns) ops[k] = optns[k];
1184
1290
  if (!ops.members) ops.members = [
@@ -1187,24 +1293,17 @@ libVES.Util = {
1187
1293
  ];
1188
1294
  return Promise.all(ops.members).then(function(ms) {
1189
1295
  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?)');
1296
+ ops.content = pkcs8;
1297
+ var rec = [];
1298
+ if (ops.password) return libVES.Util.PKCS5.export(function(call,optns) {
1299
+ rec[1] = optns.content;
1300
+ return Promise.resolve();
1301
+ },ops).then(function(data) {
1302
+ rec[0] = data;
1303
+ return libVES.Util.PEM.encode(libVES.Util.ASN1.encode([rec]),'ENCRYPTED PRIVATE KEY');
1207
1304
  });
1305
+ else if (ops.opentext) return libVES.Util.PEM.encode(pkcs8,'PRIVATE KEY');
1306
+ else throw new libVES.Error('Internal','No password for key export (opentext=true to export without password?)');
1208
1307
  });
1209
1308
  },
1210
1309
  fromJWK: function(jwk) {
@@ -1308,13 +1407,18 @@ libVES.Util = {
1308
1407
  EC: {
1309
1408
  import: function(args,chain,optns) {
1310
1409
  return chain('container',optns).then(function(der) {
1311
- var a = {name:'ECDH',namedCurve:libVES.Util.EC.namedCurves[String(args)]};
1312
- return crypto.subtle.importKey('spki',der,a,true,[]).catch(function() {;
1313
- return crypto.subtle.importKey('pkcs8',der,a,true,['deriveKey','deriveBits']).catch(function(e) {
1314
- console.log('PKCS8 failed, trying JWK...');
1315
- var jwk = libVES.Util.PKCS8.toJWK(der);
1316
- return crypto.subtle.importKey('jwk', jwk, a, true, jwk.key_ops);
1317
- });
1410
+ var oid = String(args);
1411
+ var curve = libVES.Util.EC.namedCurves[oid] || oid;
1412
+ var a = {name:'ECDH',namedCurve: curve};
1413
+ return crypto.subtle.importKey('spki',der,a,true,[]).catch(function() {
1414
+ return crypto.subtle.importKey('pkcs8',der,a,true,['deriveKey','deriveBits']);
1415
+ }).catch(function(e) {
1416
+ console.log('PKCS8 failed, trying JWK...');
1417
+ var jwk = libVES.Util.PKCS8.toJWK(der);
1418
+ return crypto.subtle.importKey('jwk', jwk, a, true, jwk.key_ops);
1419
+ }).catch(function(e) {
1420
+ console.log('trying WasmECDH...');
1421
+ return libVES.Algo.ECDH.importWasm(curve, der);
1318
1422
  });
1319
1423
  });
1320
1424
  },
@@ -1399,6 +1503,7 @@ libVES.Util.OID['1.2.840.113549.2.7'] = libVES.getModuleFunc(libVES, ['Util', 'H
1399
1503
  libVES.Util.OID['1.2.840.113549.2.9'] = libVES.getModuleFunc(libVES, ['Util', 'Hash', 'SHA256']);
1400
1504
  libVES.Util.OID['1.2.840.113549.2.10'] = libVES.getModuleFunc(libVES, ['Util', 'Hash', 'SHA384']);
1401
1505
  libVES.Util.OID['1.2.840.113549.2.11'] = libVES.getModuleFunc(libVES, ['Util', 'Hash', 'SHA512']);
1506
+ libVES.Util.OID['1.3.6.1.4.1.53675.3.5'] = libVES.getModuleFunc(libVES, ['Algo', 'OQS', 'Util']);
1402
1507
 
1403
1508
  libVES.Math = {
1404
1509
  pad: function(a,n) {
@@ -1622,7 +1727,7 @@ libVES.Object.prototype = {
1622
1727
  if (self.fieldClass[k]) return (clsf = function(v) {
1623
1728
  if (v instanceof libVES.Object) return v;
1624
1729
  else if (v instanceof Array) return v.map(function(vv) { return clsf(vv); });
1625
- else return new (self.fieldClass[k])(v,self.VES);
1730
+ else if (v) return new (self.fieldClass[k])(v,self.VES);
1626
1731
  })(v);
1627
1732
  return v;
1628
1733
  };
@@ -1639,6 +1744,34 @@ libVES.Object.prototype = {
1639
1744
  return self[fld];
1640
1745
  });
1641
1746
  },
1747
+ getFields: function(fldlst, force) {
1748
+ var self = this;
1749
+ var flds = {};
1750
+ for (var i = 0; i < this.fieldSets.length; i++) {
1751
+ for (var k in this.fieldSets[i]) if (fldlst[k]) {
1752
+ for (var k in this.fieldSets[i]) if ((force || !this[k]) && !(flds[k] instanceof Object)) flds[k] = this.fieldSets[i][k];
1753
+ break;
1754
+ }
1755
+ }
1756
+ for (var k in fldlst) if ((force || !this[k]) && !(flds[k] instanceof Object)) flds[k] = fldlst[k];
1757
+ for (var k in flds) {
1758
+ this.loadFields(flds);
1759
+ break;
1760
+ }
1761
+ var plst = [];
1762
+ for (var k in fldlst) {
1763
+ plst.push(Promise.resolve(this[k]).then(function(v) {
1764
+ if (!(v instanceof libVES.Object)) return v;
1765
+ return v.getFields(fldlst[k], force);
1766
+ }));
1767
+ }
1768
+ var rs = {};
1769
+ return Promise.all(plst).then(function(lst) {
1770
+ var i = 0;
1771
+ for (var k in fldlst) rs[k] = lst[i++];
1772
+ return rs;
1773
+ });
1774
+ },
1642
1775
  getField: function(fld,fldlst,force) {
1643
1776
  var self = this;
1644
1777
  if (!this[fld] || force) {
@@ -1780,6 +1913,22 @@ libVES.File = function(data,VES,refs) {
1780
1913
  this.init(data,VES,refs);
1781
1914
  };
1782
1915
 
1916
+ libVES.Event = function(data, VES, refs) {
1917
+ this.init(data, VES, refs);
1918
+ };
1919
+
1920
+ libVES.Session = function(data, VES, refs) {
1921
+ this.init(data, VES, refs);
1922
+ };
1923
+
1924
+ libVES.oldDomain = libVES.Domain;
1925
+ libVES.Domain = function(dom, VES) {
1926
+ this.init({id: (dom ? dom : VES.domain)}, VES);
1927
+ };
1928
+ (function(old) {
1929
+ if (old) for (var k in old) libVES.Domain[k] = old[k];
1930
+ })(libVES.oldDomain);
1931
+
1783
1932
  libVES.User.prototype = new libVES.Object({
1784
1933
  apiUri: 'users',
1785
1934
  fieldList: {id: true, email: true, type: true, firstName: true, lastName: true},
@@ -1951,12 +2100,14 @@ libVES.VaultKey.prototype = new libVES.Object({
1951
2100
  });
1952
2101
  },
1953
2102
  generate: function(veskey,optns) {
2103
+ if (!optns) optns = this.VES.keyOptions;
1954
2104
  var self = this;
2105
+ var a;
1955
2106
  var wc = optns && optns.privateKey ? libVES.Algo.acquire(optns.privateKey).then(function(wc) {
1956
2107
  self.setField('algo',wc.engine.tag);
1957
2108
  if (!wc.privateKey) throw new libVES.Error('InvalidValue','Private key expected');
1958
2109
  return wc;
1959
- }) : (optns && optns.algo ? self.setField('algo',optns.algo) : Promise.resolve()).then(function() {
2110
+ }) : (optns && (a = libVES.Algo.fromKeyOptions(optns)) ? self.setField('algo', a) : Promise.resolve()).then(function() {
1960
2111
  return self.engine().then(function(e) {
1961
2112
  return e.generate(optns).then(function(ks) {
1962
2113
  ks.engine = e;
@@ -2102,12 +2253,20 @@ libVES.VaultKey.prototype = new libVES.Object({
2102
2253
  },
2103
2254
  matchVaults: function(vaultKeys) {
2104
2255
  return Promise.resolve(false);
2256
+ },
2257
+ getKeyOptions: function() {
2258
+ var self = this;
2259
+ return self.engine().then(function(e) {
2260
+ return self.getPublicCryptoKey().then(function(pub) {
2261
+ return e.getKeyOptions(pub);
2262
+ });
2263
+ });
2105
2264
  }
2106
2265
  });
2107
2266
 
2108
2267
  libVES.VaultItem.prototype = new libVES.Object({
2109
2268
  apiUri: 'vaultItems',
2110
- fieldList: {id: true},
2269
+ fieldList: {id: true, deleted: true, file: true},
2111
2270
  fieldClass: {vaultKey: libVES.VaultKey, file: libVES.File},
2112
2271
  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
2272
  defaultCipher: 'AES256GCM',
@@ -2164,6 +2323,9 @@ libVES.VaultItem.prototype = new libVES.Object({
2164
2323
  getFile: function() {
2165
2324
  return this.getField('file');
2166
2325
  },
2326
+ getDeleted: function() {
2327
+ return this.getField('deleted');
2328
+ },
2167
2329
  parse: function(buf) {
2168
2330
  var self = this;
2169
2331
  return this.getType().then(function(type) {
@@ -2228,7 +2390,8 @@ libVES.VaultItem.prototype = new libVES.Object({
2228
2390
  });
2229
2391
  });
2230
2392
  }).then(function() {
2231
- if (save || save === undefined) return self.post().then(function() {
2393
+ if (save || save === undefined) return self.post(undefined, undefined, ((save instanceof Object) ? save : undefined)).then(function() {
2394
+ delete(self.vaultEntries);
2232
2395
  return self;
2233
2396
  });
2234
2397
  return self;
@@ -2284,6 +2447,12 @@ libVES.VaultItem.prototype = new libVES.Object({
2284
2447
  return rs;
2285
2448
  });
2286
2449
  });
2450
+ },
2451
+ delete: function() {
2452
+ var self = this;
2453
+ return self.getId().then(function(id) {
2454
+ return this.VES.post(self.apiUri + '/' + id, {'$op': 'delete'});
2455
+ });
2287
2456
  }
2288
2457
  });
2289
2458
  libVES.VaultItem.Type = {
@@ -2332,7 +2501,7 @@ libVES.VaultItem.Type.password = libVES.VaultItem.Type.string;
2332
2501
 
2333
2502
  libVES.File.prototype = new libVES.Object({
2334
2503
  apiUri: 'files',
2335
- fieldList: {id: true},
2504
+ fieldList: {id: true, externals: true},
2336
2505
  fieldClass: {externals: libVES.External, creator: libVES.User},
2337
2506
  getExternals: function() {
2338
2507
  return this.getField('externals');
@@ -2358,9 +2527,70 @@ libVES.External.prototype = new libVES.Object({
2358
2527
  }
2359
2528
  });
2360
2529
 
2530
+
2531
+ libVES.Event.prototype = new libVES.Object({
2532
+ apiUri: 'events',
2533
+ fieldList: {id: true, recordedAt: true, vaultKey: true, vaultItem: true, user: true},
2534
+ fieldClass: {vaultKey: libVES.VaultKey, vaultItem: libVES.VaultItem, user: libVES.User, creator: libVES.User, session: libVES.Session},
2535
+ getType: function() {
2536
+ return this.getField('type');
2537
+ },
2538
+ getVaultKey: function() {
2539
+ return this.getField('vaultKey');
2540
+ },
2541
+ getVaultItem: function() {
2542
+ return this.getField('vaultItem');
2543
+ },
2544
+ getUser: function() {
2545
+ return this.getField('user');
2546
+ },
2547
+ getCreator: function() {
2548
+ return this.getField('creator');
2549
+ },
2550
+ getSession: function() {
2551
+ return this.getField('session');
2552
+ }
2553
+ });
2554
+
2555
+ libVES.Session.prototype = new libVES.Object({
2556
+ apiUri: 'sessions',
2557
+ fieldList: {id: true, createdAt: true, expiresAt: true, vaultKey: true, user: true},
2558
+ fieldClass: {vaultKey: libVES.VaultKey, user: libVES.User},
2559
+ getVaultKey: function() {
2560
+ return this.getField('vaultKey');
2561
+ },
2562
+ getUser: function() {
2563
+ return this.getField('user');
2564
+ },
2565
+ getRemote: function() {
2566
+ return this.getField('remote');
2567
+ },
2568
+ getUserAgent: function() {
2569
+ return this.getField('userAgent');
2570
+ }
2571
+ });
2572
+
2573
+ libVES.Domain.prototype = new libVES.Object({
2574
+ apiUri: 'domains',
2575
+ fieldList: {id: true},
2576
+ fieldClass: {vaultKeys: libVES.VaultKey, vaultItems: libVES.VaultItem, creator: libVES.User},
2577
+ fieldSets: [{vaultItems: {id: true, type: true, file: {creator: true, externals: true}, deleted: true}, vaultKeys: {id: true, type: true, user: {id: true}, algo: true, externals: {id: true}}}],
2578
+ getCreator: function() {
2579
+ return this.getField('creator');
2580
+ },
2581
+ getVaultKeys: function() {
2582
+ return this.getField('vaultKeys');
2583
+ },
2584
+ getVaultItems: function() {
2585
+ return this.getField('vaultItems');
2586
+ }
2587
+ });
2588
+
2589
+
2361
2590
  libVES.Algo = {
2362
2591
  ECDH: {
2363
2592
  tag: 'ECDH',
2593
+ defaultCurve: 'P-521',
2364
2594
  decrypt: function(k,buf) {
2365
2595
  var b = new Uint8Array(buf);
2366
2596
  var data = libVES.Util.ASN1.decode(b);
@@ -2384,7 +2614,12 @@ libVES.Algo = {
2384
2614
  return libVES.Algo.ECDH.eKey(k).then(function(eKey) {
2385
2615
  return libVES.Algo.ECDH.cipher(eKey.privateKey,k).then(function(ci) {
2386
2616
  return Promise.all([
2387
- crypto.subtle.exportKey('spki',eKey.publicKey),
2617
+ ((k instanceof CryptoKey)
2618
+ ? crypto.subtle.exportKey('spki',eKey.publicKey)
2619
+ : libVES.Algo.ECDH.wasm().then(function(wasm) {
2620
+ return libVES.Util.Key.toPKCS(wasm.getpub(eKey.publicKey), null, libVES.Algo.ECDH.asn1hdr(wasm.getoid(eKey.publicKey)));
2621
+ })
2622
+ ),
2388
2623
  ci.encrypt(buf,true)
2389
2624
  ]).then(function(bufs) {
2390
2625
  var buf = new Uint8Array(bufs[0].byteLength + bufs[1].byteLength);
@@ -2399,21 +2634,32 @@ libVES.Algo = {
2399
2634
  });
2400
2635
  },
2401
2636
  eKey: function(pub) {
2402
- return crypto.subtle.exportKey('jwk',pub).then(function(kdata) {
2637
+ if (pub instanceof CryptoKey) return crypto.subtle.exportKey('jwk',pub).then(function(kdata) {
2403
2638
  return crypto.subtle.generateKey({name:'ECDH',namedCurve: kdata.crv},true,['deriveKey','deriveBits']).catch(function(e) {
2404
2639
  throw new libVES.Error('InvalidValue','Error generating ECIES ephemeral',{error: e});
2405
2640
  });
2406
2641
  });
2642
+ return this.wasm().then(function(wasm) {
2643
+ var k = wasm.init(pub.curve);
2644
+ wasm.generate(k);
2645
+ return wasm.privpub(k);
2646
+ });
2647
+ },
2648
+ derive: function(priv, pub) {
2649
+ if (pub instanceof CryptoKey) return Promise.resolve(libVES.Algo.ECDH.curveBytes[pub.algorithm.namedCurve] || crypto.subtle.exportKey('jwk', pub).then(function(jwk) {
2650
+ return jwk.x.length * 3 / 4;
2651
+ })).then(function(len) {
2652
+ return crypto.subtle.deriveBits({name: 'ECDH', public: pub}, priv, 8 * len);
2653
+ });
2654
+ return this.wasm().then(function(wasm) {
2655
+ return wasm.derive(priv, pub);
2656
+ });
2407
2657
  },
2408
- cipher: function(priv,pub) {
2658
+ cipher: function(priv, pub) {
2409
2659
  return libVES.getModule(libVES.Cipher,'AES256GCMp').then(function(m) {
2410
- return Promise.resolve(libVES.Algo.ECDH.curveBytes[pub.algorithm.namedCurve] || crypto.subtle.exportKey('jwk',pub).then(function(jwk) {
2411
- return jwk.x.length * 3 / 4;
2412
- })).then(function(len) {
2413
- return crypto.subtle.deriveBits({name:'ECDH',public:pub},priv,8 * len).then(function(raw) {
2414
- return crypto.subtle.digest({name:'SHA-384'},raw).then(function(buf) {
2415
- return new m(new Uint8Array(buf).slice(0,m.prototype.keySize + m.prototype.ivSize));
2416
- });
2660
+ return libVES.Algo.ECDH.derive(priv, pub).then(function(raw) {
2661
+ return crypto.subtle.digest({name:'SHA-384'},raw).then(function(buf) {
2662
+ return new m(new Uint8Array(buf).slice(0,m.prototype.keySize + m.prototype.ivSize));
2417
2663
  });
2418
2664
  });
2419
2665
  });
@@ -2448,13 +2694,22 @@ libVES.Algo = {
2448
2694
  }).then(function(der) {
2449
2695
  return libVES.Util.PEM.encode(der, 'PUBLIC KEY');
2450
2696
  });
2451
- }
2697
+ } else return this.wasm().then(function(wasm) {
2698
+ return libVES.Util.Key.export(wasm.getpub(data), wasm.getpriv(data), libVES.Algo.ECDH.asn1hdr(wasm.getoid(data)), optns);
2699
+ });
2452
2700
  throw new libVES.Error('Internal', "Unknown type of key object");
2453
2701
  },
2454
2702
  generate: function(optns) {
2455
- var op = {name:'ECDH', namedCurve:'P-384'};
2703
+ var op = {name: 'ECDH', namedCurve: this.defaultCurve};
2456
2704
  if (optns) for (var k in optns) op[k] = optns[k];
2457
- return crypto.subtle.generateKey(op,true,['deriveKey','deriveBits']);
2705
+ return crypto.subtle.generateKey(op, true, ['deriveKey', 'deriveBits']).catch(function(e) {
2706
+ console.log('ECDH generateKey failed, trying wasm...', e, op);
2707
+ return libVES.Algo.ECDH.wasm().then(function(wasm) {
2708
+ var k = wasm.init(op.namedCurve);
2709
+ if (!k || !wasm.generate(k)) throw new libVES.Error('InvalidValue', 'WasmECDH key generation error (unsupported curve?)');
2710
+ return wasm.privpub(k);
2711
+ });
2712
+ });
2458
2713
  },
2459
2714
  getPublic: function(priv) {
2460
2715
  return crypto.subtle.exportKey('jwk',priv).then(function(k) {
@@ -2467,7 +2722,48 @@ libVES.Algo = {
2467
2722
  y: k.y
2468
2723
  },{name:'ECDH'},true,[]);
2469
2724
  });
2470
- }
2725
+ },
2726
+ getKeyOptions: function(key) {
2727
+ if (key instanceof CryptoKey) return crypto.subtle.exportKey('jwk', key).then(function(k) {
2728
+ return {namedCurve: k.crv};
2729
+ });
2730
+ return {namedCurve: k.curve};
2731
+ },
2732
+ asn1hdr: function(oid) {
2733
+ return [new libVES.Util.OID(this.OID), new libVES.Util.OID(oid)];
2734
+ },
2735
+ wasm: function() {
2736
+ if (!this.wasmP) this.wasmP = (typeof(WasmECDH) == 'function' ? Promise.resolve()
2737
+ : libVES.Util.loadWasm(WasmECDHinit.baseUrl + 'WasmECDH.js')
2738
+ ).then(function() {
2739
+ return WasmECDH(WasmECDHinit);
2740
+ });
2741
+ return this.wasmP;
2742
+ },
2743
+ importWasm: function(curve, der) {
2744
+ return libVES.Algo.ECDH.wasm().then(function(wasm) {
2745
+ return libVES.Util.Key.fromDER(der, function(pub, priv, pubBits) {
2746
+ var k = wasm.init(curve);
2747
+ if (!k) return null;
2748
+ if (pub) wasm.setpub(k, pub);
2749
+ if (priv) wasm.setpriv(k, priv);
2750
+ return k;
2751
+ });
2752
+ });
2753
+ },
2754
+ getMethods: function() {
2755
+ var crvs = ['P-256', 'P-384', 'P-521'];
2756
+ return this.wasm().then(function(wasm) {
2757
+ return crvs.concat(wasm.getcurves());
2758
+ }).catch(function(e) {
2759
+ return crvs;
2760
+ }).then(function(crvs) {
2761
+ return crvs.map(function(algo) {
2762
+ return {namedCurve: algo};
2763
+ });
2764
+ });
2765
+ },
2766
+ OID: '1.2.840.10045.2.1'
2471
2767
  },
2472
2768
  RSA: {
2473
2769
  tag: 'RSA',
@@ -2526,7 +2822,7 @@ libVES.Algo = {
2526
2822
  throw new libVES.Error('Internal',"Unknown type of key object");
2527
2823
  },
2528
2824
  generate: function(optns) {
2529
- var op = {name:'RSA-OAEP', modulusLength:2048, publicExponent:new Uint8Array([1,0,1]), hash:'SHA-1'};
2825
+ var op = {name:'RSA-OAEP', modulusLength:4096, publicExponent:new Uint8Array([1,0,1]), hash:'SHA-256'};
2530
2826
  if (optns) for (var k in optns) op[k] = optns[k];
2531
2827
  return crypto.subtle.generateKey(op,true,['decrypt','encrypt']);
2532
2828
  },
@@ -2539,9 +2835,25 @@ libVES.Algo = {
2539
2835
  key_ops: ['encrypt'],
2540
2836
  kty: 'RSA',
2541
2837
  n: k.n
2542
- },{name:'RSA-OAEP',hash:'SHA-1'},true,['encrypt']);
2838
+ },{name:'RSA-OAEP',hash:'SHA-256'},true,['encrypt']);
2543
2839
  });
2544
- }
2840
+ },
2841
+ getKeyOptions: function(key) {
2842
+ return crypto.subtle.exportKey('jwk', key).then(function(k) {
2843
+ return {modulusLength: ((k.n.length * 6) >> 3) * 8, publicExponent: libVES.Util.B64ToByteArray(k.e)};
2844
+ });
2845
+ },
2846
+ getMethods: function() {
2847
+ var bits = [];
2848
+ var s = 128;
2849
+ for (var i = 640; i <= 16384; i += s) {
2850
+ bits.push(i);
2851
+ if (i / s >= 8) s <<= 1;
2852
+ }
2853
+ return Promise.resolve(bits.map(function(b) {
2854
+ return {modulusLength: b};
2855
+ }));
2856
+ },
2545
2857
  },
2546
2858
  RSA_PKCS1_15: {
2547
2859
  tag: 'RSA_PKCS1_15',
@@ -2578,9 +2890,107 @@ libVES.Algo = {
2578
2890
  }
2579
2891
  });
2580
2892
  },
2893
+ fromKeyOptions: function(optns) {
2894
+ if (optns.namedCurve) return 'ECDH';
2895
+ if (optns.oqsAlgo) return 'OQS';
2896
+ if (optns.modulusLength) return 'RSA';
2897
+ },
2581
2898
  toString: function() {
2582
2899
  return 'libVES.Algo';
2583
- }
2900
+ },
2901
+ all: ['RSA', 'ECDH']
2902
+ };
2903
+
2904
+ WasmECDHinit = {
2905
+ Key: function() {},
2906
+ init: function(curve) {
2907
+ var a = new Uint8Array(libVES.Util.StringToByteArray(curve));
2908
+ var arg1 = this.buf(a.byteLength + 1);
2909
+ arg1.set(a);
2910
+ arg1.set([0], a.byteLength);
2911
+ var ptr = this._WasmECDH_new(arg1.byteOffset);
2912
+ if (!ptr) return null;
2913
+ var key = new this.Key();
2914
+ key.ptr = ptr;
2915
+ key.curve = this.getcurve(key);
2916
+ return key;
2917
+ },
2918
+ buf: function(len) {
2919
+ return new Uint8Array(this.asm.memory.buffer, this._WasmECDH_buf, len);
2920
+ },
2921
+ str: function(ptr) {
2922
+ if (!ptr) return null;
2923
+ var b = new Uint8Array(this.asm.memory.buffer, ptr);
2924
+ return libVES.Util.ByteArrayToString(b.slice(0, b.indexOf(0)));
2925
+ },
2926
+ generate: function(key) {
2927
+ key.private = true;
2928
+ return this._WasmECDH_generate(key.ptr);
2929
+ },
2930
+ setpub: function(key, pub) {
2931
+ var arg1 = this.buf(pub.byteLength);
2932
+ arg1.set(pub);
2933
+ return this._WasmECDH_setpub(key.ptr, arg1.byteOffset, arg1.byteLength);
2934
+ },
2935
+ setpriv: function(key, priv) {
2936
+ key.private = true;
2937
+ var arg1 = this.buf(priv.byteLength);
2938
+ arg1.set(priv);
2939
+ return this._WasmECDH_setpriv(key.ptr, arg1.byteOffset, arg1.byteLength);
2940
+ },
2941
+ getpub: function(key) {
2942
+ var l = this._WasmECDH_getpub(key.ptr);
2943
+ if (l <= 0) return null;
2944
+ var rs = new Uint8Array(l);
2945
+ rs.set(this.buf(l));
2946
+ return rs;
2947
+ },
2948
+ getpriv: function(key) {
2949
+ if (!key.private) return null;
2950
+ var l = this._WasmECDH_getpriv(key.ptr);
2951
+ if (l <= 0) return null;
2952
+ var rs = new Uint8Array(l);
2953
+ rs.set(this.buf(l));
2954
+ return rs;
2955
+ },
2956
+ getcurve: function(key) {
2957
+ return this.str(this._WasmECDH_getcurve(key.ptr));
2958
+ },
2959
+ getoid: function(key) {
2960
+ return this.str(this._WasmECDH_getoid(key.ptr));
2961
+ },
2962
+ derive: function(priv, pub) {
2963
+ var l = this._WasmECDH_derive(priv.ptr, pub.ptr);
2964
+ if (l <= 0) return null;
2965
+ var rs = new Uint8Array(l);
2966
+ rs.set(this.buf(l));
2967
+ return rs;
2968
+ },
2969
+ privpub: function(priv) {
2970
+ var pub = new this.Key();
2971
+ pub.ptr = priv.ptr;
2972
+ pub.curve = priv.curve;
2973
+ return {privateKey: priv, publicKey: pub};
2974
+ },
2975
+ free: function(key) {
2976
+ this._WasmECDH_free(key.ptr);
2977
+ },
2978
+ getcurves: function() {
2979
+ var lst = this._WasmECDH_listinit(1024);
2980
+ var crvs = [];
2981
+ var c;
2982
+ for (var i = 0; (c = this._WasmECDH_listget(lst, i)); i++) {
2983
+ var crv = this.str(c);
2984
+ if (crv == '') continue;
2985
+ crvs.push(crv);
2986
+ }
2987
+ this._WasmECDH_listfree(lst);
2988
+ return crvs;
2989
+ },
2990
+ locateFile: function(file) {
2991
+ return this.baseUrl + file;
2992
+ },
2993
+ baseUrl: 'https://ves.host/pub/'
2584
2994
  };
2585
2995
 
2586
2996
  libVES.Cipher = function(data) {
@@ -3128,10 +3538,14 @@ libVES.Recovery.prototype = {
3128
3538
  return this.getMyToken().then(function(tkn) {
3129
3539
  if (!tkn) throw new libVES.Error('InvalidValue','No assistance available');
3130
3540
  return self.vaultKey.getUser().then(function(user) {
3131
- return tkn.vaultItem.shareWith(assist ? [tkn.user,user] : [tkn.user]).then(function() {
3132
- self.tokens = undefined;
3133
- self.vaultKey.vaultItems = undefined;
3134
- return true;
3541
+ return self.vaultKey.VES.elevateAuth().catch(function(e) {
3542
+ return undefined;
3543
+ }).then(function(optns) {
3544
+ return tkn.vaultItem.shareWith((assist ? [tkn.user,user] : [tkn.user]), undefined, optns).then(function() {
3545
+ self.tokens = undefined;
3546
+ self.vaultKey.vaultItems = undefined;
3547
+ return true;
3548
+ });
3135
3549
  });
3136
3550
  });
3137
3551
  });
@@ -3380,7 +3794,7 @@ libVES.Flow.prototype.pubJWK = function(org) {
3380
3794
  return libVES.Flow.jwkPub(jwk);
3381
3795
  });
3382
3796
  }) : Promise.resolve(sessionStorage['VESflow|' + org]).then(function(k) {
3383
- if (!k) throw {code: 'NotFound', message: 'No public key stored for ' + org};
3797
+ if (!k) throw new libVES.Error('NotFound', 'No public key stored for ' + org);
3384
3798
  return JSON.parse(k);
3385
3799
  }));
3386
3800
  };
@@ -3407,7 +3821,7 @@ libVES.Flow.prototype.cipher = function(url) {
3407
3821
  libVES.Flow.prototype.encrypt = function(url, val) {
3408
3822
  var self = this;
3409
3823
  return Promise.resolve(val || this.value()).then(function(val) {
3410
- if (val == null) throw {code: 'NoData', message: 'Empty value'};
3824
+ if (val == null) throw new libVES.Error('NoData', 'Empty value');
3411
3825
  return self.cipher(url).then(function(ci) {
3412
3826
  var iv = new Uint8Array(12);
3413
3827
  crypto.getRandomValues(iv);
@@ -3498,7 +3912,7 @@ libVES.Flow.prototype.recv = function(dval) {
3498
3912
  tk = t;
3499
3913
  return true;
3500
3914
  });
3501
- if (tk == null) throw {code: 'NotFound', message: 'No valid token in the source url'};
3915
+ if (tk == null) throw new libVES.Error('NotFound', 'No valid token in the source url');
3502
3916
  return Promise.resolve(self.source(src)).then(function() {
3503
3917
  if (dval) for (var k in dval) if (tk[k] === undefined) tk[k] = dval[k];
3504
3918
  return self.recvToken(tk);
@@ -3509,7 +3923,7 @@ libVES.Flow.prototype.recv = function(dval) {
3509
3923
  libVES.Flow.prototype.recvToken = function(tk) {
3510
3924
  var org = libVES.Flow.toOrigin(tk.url);
3511
3925
  if (org != this.origin && tk.key) sessionStorage['VESflow|' + org] = JSON.stringify(tk.key);
3512
- if (!tk.enc) return Promise.reject({url: tk.url, code: 'Incomplete', message: 'Missing encrypted data'});
3926
+ if (!tk.enc) return Promise.reject(new libVES.Error('Incomplete', 'Missing encrypted data', {url: tk.url}));
3513
3927
  return this.decrypt(tk.enc, org);
3514
3928
  };
3515
3929
 
@@ -3524,7 +3938,7 @@ libVES.Flow.prototype.get = function() {
3524
3938
  self.url = document.location.href;
3525
3939
  return self.addToken(e.url).then(function(url) {
3526
3940
  document.location.replace(url);
3527
- throw {code: 'Reload', message: 'Completing the key exchange'};
3941
+ throw new libVES.Error('Redirect', 'Completing the key exchange');
3528
3942
  });
3529
3943
  }
3530
3944
  if (!data) throw e;
@@ -3538,13 +3952,13 @@ libVES.Flow.prototype.store = function(url) {
3538
3952
  this.sent = 1;
3539
3953
  return Promise.resolve(sessionStorage['VESflow.' + this.name + '>' + libVES.Flow.toOrigin(url)] = history.state['VESflow.' + this.name]);
3540
3954
  }
3541
- return Promise.reject({code: 'NotFound', message: 'Value is not set'});
3955
+ return Promise.reject(new libVES.Error('NotFound', 'Value is not set'));
3542
3956
  };
3543
3957
 
3544
3958
  libVES.Flow.prototype.fetch = function(url) {
3545
3959
  var self = this;
3546
3960
  return Promise.resolve(sessionStorage['VESflow.' + self.name + '>' + libVES.Flow.toOrigin(url)]).then(function(ctext) {
3547
- if (!ctext) throw {code: 'NotFound', message: 'Not in the session storage'};
3961
+ if (!ctext) throw new libVES.Error('NotFound', 'Not in the session storage');
3548
3962
  return self.decrypt(ctext).then(function(data) {
3549
3963
  self.erase(url);
3550
3964
  return data;
@@ -3660,4 +4074,325 @@ libVES.Auth.prototype.verify = function(token, auth) {
3660
4074
  });
3661
4075
  };
3662
4076
 
4077
+
4078
+ libVES.Algo.OQS = {
4079
+ tag: 'OQS',
4080
+ wasm: function() {
4081
+ if (!this.wasmP) this.wasmP = (typeof(WasmOQS) == 'function' ? Promise.resolve()
4082
+ : libVES.Util.loadWasm(WasmOQSinit.baseUrl + 'WasmOQS.js')
4083
+ ).then(function() {
4084
+ return WasmOQS(WasmOQSinit);
4085
+ });
4086
+ return this.wasmP;
4087
+ },
4088
+ checkLimits: function(k) {
4089
+ return k.pub.byteLength + k.priv.byteLength <= libVES.maxKeyLen && k.ctextlen + 64 <= libVES.maxEncDataLen;
4090
+ },
4091
+ decrypt: function(k,buf) {
4092
+ return this.wasm().then(function(wasm) {
4093
+ var b = new Uint8Array(buf);
4094
+ if (b.byteLength <= k.ctextlen) throw new libVES.Error('InvalidValue', 'Ciphertext is too short');
4095
+ var secret = wasm.decaps(k, b.slice(0, k.ctextlen));
4096
+ if (!secret) throw new libVES.Error('InvalidValue', 'OQS decryption error');
4097
+ return libVES.Algo.OQS.cipher(secret).then(function(ci) {
4098
+ return ci.decrypt(b.slice(k.ctextlen), true).catch(function(e) {
4099
+ if (e instanceof libVES.Error) throw e;
4100
+ throw new libVES.Error('InvalidValue', 'Error decrypting ECIES payload: Invalid ciphertext?',{error:e});
4101
+ });
4102
+ }).catch(function(e) {
4103
+ if (e instanceof libVES.Error) throw e;
4104
+ throw new libVES.Error('InvalidValue', 'Error negotiating ECIES cipher key: Invalid ciphertext?',{error:e});
4105
+ });
4106
+ })
4107
+ },
4108
+ encrypt: function(k, buf) {
4109
+ return this.wasm().then(function(wasm) {
4110
+ var ctext = wasm.encaps(k);
4111
+ if (!ctext) throw new libVES.Error('InvalidValue', 'Error generating OQS secret');
4112
+ return libVES.Algo.OQS.cipher(wasm.decaps(k)).then(function(ci) {
4113
+ return ci.encrypt(buf, true).then(function(ctext2) {
4114
+ var buf = new Uint8Array(ctext.byteLength + ctext2.byteLength);
4115
+ buf.set(new Uint8Array(ctext),0);
4116
+ buf.set(new Uint8Array(ctext2),ctext.byteLength);
4117
+ return buf;
4118
+ });
4119
+ }).catch(function(e) {
4120
+ if (e instanceof libVES.Error) throw e;
4121
+ throw new libVES.Error('InvalidValue', 'Error generating ECIES cipher',{error:e});
4122
+ });
4123
+ });
4124
+ },
4125
+ cipher: function(secret) {
4126
+ return libVES.getModule(libVES.Cipher,'AES256GCMp').then(function(m) {
4127
+ return crypto.subtle.digest({name:'SHA-384'}, secret).then(function(buf) {
4128
+ return new m(new Uint8Array(buf).slice(0, m.prototype.keySize + m.prototype.ivSize));
4129
+ });
4130
+ });
4131
+ },
4132
+ import: function(data,optns) {
4133
+ return libVES.Util.PEM.import(data,optns);
4134
+ },
4135
+ export: function(data, optns) {
4136
+ if (!data || !data.ptr) throw new libVES.Error('Internal', "Unknown type of key object");
4137
+ var oid = [new libVES.Util.OID(libVES.Algo.OQS.OID), libVES.Util.StringToByteArray(data.algo)];
4138
+ return libVES.Util.Key.export(data.pub, data.priv, oid, optns);
4139
+ },
4140
+ generate: function(optns) {
4141
+ var algo = optns ? optns.oqsAlgo : null;
4142
+ if (!algo) algo = this.defaultAlgo;
4143
+ return this.wasm().then(function(wasm) {
4144
+ var k = wasm.init(algo, true);
4145
+ if (!k) throw new libVES.Error('InvalidValue', 'OQS key init failed');
4146
+ if (!libVES.Algo.OQS.checkLimits(k)) throw wasm.free(k), new libVES.Error('Internal', 'OQS key is too large for VES');
4147
+ if (!wasm.generate(k)) throw wasm.free(k), new libVES.Error('Internal', 'OQS generate failed');
4148
+ var pub = new wasm.Key(k.algo);
4149
+ for (var i in k) if (i != 'priv') pub[i] = k[i];
4150
+ return {privateKey: k, publicKey: pub};
4151
+ });
4152
+ },
4153
+ getKeyOptions: function(key) {
4154
+ return {oqsAlgo: k.algo};
4155
+ },
4156
+ getMethods: function() {
4157
+ return this.wasm().then(function(wasm) {
4158
+ return wasm.getalgos().filter(function(algo) {
4159
+ var k = wasm.init(algo, true);
4160
+ if (!k) return false;
4161
+ var f = libVES.Algo.OQS.checkLimits(k);
4162
+ wasm.free(k);
4163
+ return f;
4164
+ }).map(function(algo) {
4165
+ return {oqsAlgo: algo};
4166
+ });
4167
+ });
4168
+ },
4169
+ Util: {
4170
+ import: function(args,chain,optns) {
4171
+ var algo = libVES.Util.ByteArrayToString(args);
4172
+ return chain('container').then(function(der) {
4173
+ return libVES.Util.Key.fromDER(der, function(pub, priv, pubBits) {
4174
+ return libVES.Algo.OQS.wasm().then(function(wasm) {
4175
+ var k = wasm.init(algo, !!priv);
4176
+ if (!k) throw new libVES.Error('InvalidValue', 'OQS key init failed (bad algo?)');
4177
+ var s = function(dst, src) {
4178
+ if (!dst || !src || dst.byteLength != src.byteLength) throw wasm.free(k), new libVES.Error('InvalidValue', 'Incorrect OQS key size');
4179
+ dst.set(src, 0);
4180
+ };
4181
+ if (priv) s(k.priv, priv);
4182
+ s(k.pub, pub);
4183
+ return k;
4184
+ });
4185
+ });
4186
+ });
4187
+ }
4188
+ },
4189
+ OID: '1.3.6.1.4.1.53675.3.5',
4190
+ defaultAlgo: 'Kyber768'
4191
+ };
4192
+ libVES.Algo.all.push('OQS');
4193
+
4194
+ var WasmOQSinit = {
4195
+ Key: function(algo) {
4196
+ this.algo = algo;
4197
+ },
4198
+ init: function(algo, fpriv) {
4199
+ var a = new Uint8Array(libVES.Util.StringToByteArray(algo));
4200
+ var arg1 = new Uint8Array(this.asm.memory.buffer, 16, 48);
4201
+ arg1.set(a);
4202
+ arg1.set([0], a.byteLength);
4203
+ var ptr = this._WasmOQS_new(arg1.byteOffset, fpriv);
4204
+ if (!ptr) return null;
4205
+ var key = new this.Key(algo);
4206
+ key.ptr = ptr;
4207
+ var priv = this._WasmOQS_priv(ptr);
4208
+ if (priv) key.priv = new Uint8Array(this.asm.memory.buffer, priv, this._WasmOQS_privlen(ptr));
4209
+ key.pub = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_pub(ptr), this._WasmOQS_publen(ptr));
4210
+ key.secretlen = this._WasmOQS_decaps(key.ptr, null, null);
4211
+ key.ctextlen = this._WasmOQS_encaps(key.ptr, null, null);
4212
+ return key;
4213
+ },
4214
+ generate: function(key) {
4215
+ return this._WasmOQS_generate(key.ptr) >= 0;
4216
+ },
4217
+ encaps: function(key) {
4218
+ var arg1 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_secretbuf, this._WasmOQS_decaps(key.ptr, null, null));
4219
+ var arg2 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_ctextbuf, this._WasmOQS_encaps(key.ptr, null, null));
4220
+ if (this._WasmOQS_encaps(key.ptr, arg2.byteOffset, arg1.byteOffset) <= 0) return null;
4221
+ key.secret = new Uint8Array(arg1.byteLength);
4222
+ key.secret.set(arg1);
4223
+ var ctext = new Uint8Array(arg2.byteLength);
4224
+ ctext.set(arg2);
4225
+ return ctext;
4226
+ },
4227
+ decaps: function(key, ctext) {
4228
+ var arg1 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_secretbuf, this._WasmOQS_decaps(key.ptr, null, null));
4229
+ if (ctext) {
4230
+ if (ctext.byteLength != this._WasmOQS_encaps(key.ptr, null, null)) return null;
4231
+ var arg2 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_ctextbuf, ctext.byteLength);
4232
+ arg2.set(ctext);
4233
+ if (this._WasmOQS_decaps(key.ptr, arg1.byteOffset, arg2.byteOffset) <= 0) return null;
4234
+ }
4235
+ var secret = new Uint8Array(arg1.byteLength);
4236
+ secret.set(arg1);
4237
+ return secret;
4238
+ },
4239
+ free: function(key) {
4240
+ this._WasmOQS_free(key.ptr);
4241
+ delete(key.ptr);
4242
+ },
4243
+ getalgos: function() {
4244
+ var algos = [];
4245
+ var a;
4246
+ for (var i = 0; a = this._WasmOQS_enumalgo(i); i++) {
4247
+ var s = new Uint8Array(this.asm.memory.buffer, a);
4248
+ var p = s.indexOf(0);
4249
+ if (!p) continue;
4250
+ algos.push(libVES.Util.ByteArrayToString(s.slice(0, p)));
4251
+ }
4252
+ return algos;
4253
+ },
4254
+ test: function(algo) {
4255
+ var k = this.init(algo, 1);
4256
+ this.generate(k);
4257
+ var ctext = this.encaps(k);
4258
+ var secret = this.decaps(k);
4259
+ console.log(secret);
4260
+ var secret2 = this.decaps(k, ctext);
4261
+ console.log(secret2);
4262
+ },
4263
+ locateFile: function(file) {
4264
+ return this.baseUrl + file;
4265
+ },
4266
+ baseUrl: 'https://ves.host/pub/'
4267
+ };
4268
+
4269
+
4270
+
4271
+ libVES.Watch = function(obj, optns) {
4272
+ if (obj instanceof libVES) obj = obj.domain ? (obj.externalId ? obj.getVaultKey() : new libVES.Domain(null, obj)) : obj.me();
4273
+ var self = this;
4274
+ this.object = Promise.resolve(obj).then(function(o) {
4275
+ if (o instanceof libVES.VaultKey) {
4276
+ self.uri = 'vaultKeys/';
4277
+ } else if (o instanceof libVES.VaultItem) {
4278
+ self.uri = 'vaultItems/';
4279
+ } else if (o instanceof libVES.User) {
4280
+ self.uri = 'users/';
4281
+ } else if (o instanceof libVES.Domain) {
4282
+ self.uri = 'domains/';
4283
+ } else {
4284
+ throw new libVES.Error('Internal', 'Watchable object expected');
4285
+ }
4286
+ self.VES = o.VES;
4287
+ return o;
4288
+ });
4289
+ if (optns) for (var k in optns) this[k] = optns[k];
4290
+ };
4291
+
4292
+ libVES.Watch.prototype = {
4293
+ fields: {vaultKey: {id: true, user: true, externals: true, creator: true}, vaultItem: {id: true, vaultKey: true, file: {externals: true, creator: true}}, session: {id: true, userAgent: true, remote: true, createdAt: true, expiresAt: true}},
4294
+ state: 'idle',
4295
+ timeout: 900,
4296
+ getEvents: function(start, ct, poll) {
4297
+ var self = this;
4298
+ return self.object.then(function(o) {
4299
+ return o.getId().then(function(id) {
4300
+ return (poll ? self.VES.pollUrl : '') + self.uri + id
4301
+ + '?fields=events(' + self.VES.uriListFields(self.fields) + ')%5B' + start + (ct >= 0 ? '%2B' : '') + ct + '%5D'
4302
+ + (poll ? '&poll=' + self.timeout : '');
4303
+ });
4304
+ }).then(function(url) {
4305
+ return self.VES.get(url);
4306
+ }).then(function(res) {
4307
+ if (!res.events) return null;
4308
+ return res.events.map(function(e, i) {
4309
+ return new libVES.Event(e, self.VES);
4310
+ });
4311
+ });
4312
+ },
4313
+ setState: function(st) {
4314
+ if (this.statefn) try {
4315
+ this.statefn(st, this);
4316
+ } catch(e) {}
4317
+ this.state = st;
4318
+ },
4319
+ setBusy: function(busy) {
4320
+ this.busy = busy;
4321
+ if (!busy && this.state == 'stop') this.setState('idle');
4322
+ },
4323
+ start: function(pos) {
4324
+ if (!this.eventfn) throw new libVES.Error('InvalidValue', 'eventfn is not set');
4325
+ if (this.busy) throw new libVES.Error('Internal', 'Watch instance is busy');
4326
+ var self = this;
4327
+ self.setBusy(true);
4328
+ this.setState('read');
4329
+ if (pos < 0) {
4330
+ this.next = 0;
4331
+ return this.getEvents(0, pos).then(function(evs) {
4332
+ self.setBusy(false);
4333
+ return self.received(evs.reverse());
4334
+ });
4335
+ } else {
4336
+ this.next = pos;
4337
+ return this.getEvents(pos, 0).then(function(evs) {
4338
+ self.setBusy(false);
4339
+ return self.received(evs);
4340
+ });
4341
+ }
4342
+ },
4343
+ active: function() {
4344
+ return this.state == 'read' || this.state == 'poll';
4345
+ },
4346
+ received: function(evs) {
4347
+ var self = this;
4348
+ var p;
4349
+ if (evs && evs.length) p = evs.reduce(function(v, e) {
4350
+ if (self.active()) try {
4351
+ self.eventfn(e, self);
4352
+ } catch(e) {
4353
+ console.log(e);
4354
+ }
4355
+ return e;
4356
+ }, null).getId().then(function(id) {
4357
+ self.next = id + 1;
4358
+ });
4359
+ else {
4360
+ p = Promise.resolve(null);
4361
+ if (this.state == 'read') this.setState('poll');
4362
+ }
4363
+ return p.then(function() {
4364
+ return self.request();
4365
+ });
4366
+ },
4367
+ request: function() {
4368
+ if (this.busy || !this.active()) return;
4369
+ var self = this;
4370
+ self.setBusy(true);
4371
+ return self.getEvents(self.next, 0, (self.state == 'poll')).then(function(evs) {
4372
+ self.setBusy(false);
4373
+ self.received(evs);
4374
+ }).catch(function(e) {
4375
+ self.setBusy(false);
4376
+ if (self.errorfn) try {
4377
+ self.errorfn(e, self);
4378
+ } catch(e) {
4379
+ console.log(e);
4380
+ }
4381
+ return self.retry();
4382
+ });
4383
+ },
4384
+ retry: function() {
4385
+ var self = this;
4386
+ return new Promise(function(resolve, reject) {
4387
+ window.setTimeout(function() {
4388
+ resolve(self.request());
4389
+ }, 1000);
4390
+ });
4391
+ },
4392
+ stop: function() {
4393
+ this.setState(this.busy ? 'stop' : 'idle');
4394
+ }
4395
+ };
4396
+ libVES.version = '2.16';
4397
+
3663
4398
  module.exports = libVES;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libves",
3
- "version": "2.3.1",
3
+ "version": "2.16.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.1.tgz DELETED
Binary file