libves 2.6.0 → 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.06
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,14 +432,15 @@ 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
437
  return usr.getActiveVaultKeys().then(function() {
433
438
  return [self.me(), self.getVaultKey(), usr];
434
439
  }).catch(function(e) {
435
440
  if (e.code != 'NotFound') throw e;
436
- return self.type == 'secondary' ? [self.me(), self.getVaultKey()] : [self.me()];
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;
437
444
  }).then(function(sh) {
438
445
  return Promise.all(sh);
439
446
  }).then(function(sh) {
@@ -451,18 +458,6 @@ libVES.prototype = {
451
458
  crypto.getRandomValues(buf);
452
459
  return Promise.resolve(libVES.Util.ByteArrayToB64(buf));
453
460
  },
454
- getVESkeyE2E: function(veskey,usr) {
455
- var self = this;
456
- return veskey.then(function(v) {
457
- return libVES.getModule(libVES.E2E,['Dialog','TempKey']).then(function(cls) {
458
- return new cls({
459
- user: usr,
460
- e2e: self.e2e,
461
- tempKey: v
462
- });
463
- });
464
- });
465
- },
466
461
  setVESkey: function(veskey,lost,options) {
467
462
  var self = this;
468
463
  return this.me().then(function(me) {
@@ -658,7 +653,7 @@ libVES.prototype = {
658
653
  return Promise.resolve(shareWith || self.getFileItem(fileRef).then(function(vi) {
659
654
  return vi.getShareList();
660
655
  }).catch(function(e) {
661
- return self.usersToKeys([{domain: (fileRef.domain || VES.domain)}]);
656
+ return self.usersToKeys([{domain: VES.domain, externalId: VES.externalId}]);
662
657
  })).then(function(shareWith) {
663
658
  return vaultItem.shareWith(shareWith,value);
664
659
  });
@@ -681,8 +676,8 @@ libVES.prototype = {
681
676
  });
682
677
  },
683
678
  deleteFile: function(fileRef) {
684
- return this.getFile(fileRef).then(function(file) {
685
- return file.delete();
679
+ return this.getFileItem(fileRef).then(function(item) {
680
+ return item.delete();
686
681
  });
687
682
  },
688
683
  newSecret: function(cls) {
@@ -857,9 +852,11 @@ libVES.prototype = {
857
852
  return vkey.rekey(optns);
858
853
  });
859
854
  else return vkey.getVaultItems().then(function(vis) {
860
- return Promise.all(vis.map(function(vi, i) {
861
- return vi.reshareWith([user]);
862
- }));
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
+ });
863
860
  });
864
861
  });
865
862
  });
@@ -871,11 +868,27 @@ libVES.prototype = {
871
868
  }
872
869
  });
873
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
+ }
874
882
  }
875
883
  };
876
884
 
877
- 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);
878
887
  this.code = code;
888
+ this.init(msg, optns);
889
+ };
890
+
891
+ libVES.Error.prototype.init = function(msg, optns) {
879
892
  this.message = msg;
880
893
  if (optns) for (var k in optns) this[k] = optns[k];
881
894
  };
@@ -884,6 +897,32 @@ libVES.Error.prototype.toString = function() {
884
897
  return this.message || this.code;
885
898
  };
886
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
+
887
926
  libVES.getModule = function(sectn,mods) {
888
927
  var mod;
889
928
  if (mods instanceof Array) mod = mods[0];
@@ -904,6 +943,9 @@ libVES.getModuleFunc = function(sectn,mod,then) {
904
943
  libVES.loadModule = function(sectn,mod) {
905
944
  return Promise.reject(new libVES.Error('Internal',"Cannot load " + sectn + '.' + mod));
906
945
  };
946
+ libVES.maxKeyLen = 48896;
947
+ libVES.maxEncDataLen = 32768;
948
+
907
949
 
908
950
  if (!libVES.Domain) libVES.Domain = {};
909
951
 
@@ -982,6 +1024,16 @@ libVES.Util = {
982
1024
  }
983
1025
  return rs;
984
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
+ },
985
1037
  PEM: {
986
1038
  toDER: function(pem) {
987
1039
  var pp = pem.match(/-----BEGIN.*?-----\s*\r?\n([A-Za-z0-9\/\+\=\s\r\n]*)-----END/);
@@ -1136,6 +1188,43 @@ libVES.Util = {
1136
1188
  this.value = rs.join('.');
1137
1189
  } else this.value = s;
1138
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
+ },
1139
1228
  PKCS1: {
1140
1229
  import: function(args,chain,optns) {
1141
1230
  return chain('container',optns).then(function(der) {
@@ -1318,13 +1407,18 @@ libVES.Util = {
1318
1407
  EC: {
1319
1408
  import: function(args,chain,optns) {
1320
1409
  return chain('container',optns).then(function(der) {
1321
- var a = {name:'ECDH',namedCurve:libVES.Util.EC.namedCurves[String(args)]};
1322
- return crypto.subtle.importKey('spki',der,a,true,[]).catch(function() {;
1323
- return crypto.subtle.importKey('pkcs8',der,a,true,['deriveKey','deriveBits']).catch(function(e) {
1324
- console.log('PKCS8 failed, trying JWK...');
1325
- var jwk = libVES.Util.PKCS8.toJWK(der);
1326
- return crypto.subtle.importKey('jwk', jwk, a, true, jwk.key_ops);
1327
- });
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);
1328
1422
  });
1329
1423
  });
1330
1424
  },
@@ -1633,7 +1727,7 @@ libVES.Object.prototype = {
1633
1727
  if (self.fieldClass[k]) return (clsf = function(v) {
1634
1728
  if (v instanceof libVES.Object) return v;
1635
1729
  else if (v instanceof Array) return v.map(function(vv) { return clsf(vv); });
1636
- else return new (self.fieldClass[k])(v,self.VES);
1730
+ else if (v) return new (self.fieldClass[k])(v,self.VES);
1637
1731
  })(v);
1638
1732
  return v;
1639
1733
  };
@@ -1650,6 +1744,34 @@ libVES.Object.prototype = {
1650
1744
  return self[fld];
1651
1745
  });
1652
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
+ },
1653
1775
  getField: function(fld,fldlst,force) {
1654
1776
  var self = this;
1655
1777
  if (!this[fld] || force) {
@@ -1791,6 +1913,22 @@ libVES.File = function(data,VES,refs) {
1791
1913
  this.init(data,VES,refs);
1792
1914
  };
1793
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
+
1794
1932
  libVES.User.prototype = new libVES.Object({
1795
1933
  apiUri: 'users',
1796
1934
  fieldList: {id: true, email: true, type: true, firstName: true, lastName: true},
@@ -1962,12 +2100,14 @@ libVES.VaultKey.prototype = new libVES.Object({
1962
2100
  });
1963
2101
  },
1964
2102
  generate: function(veskey,optns) {
2103
+ if (!optns) optns = this.VES.keyOptions;
1965
2104
  var self = this;
2105
+ var a;
1966
2106
  var wc = optns && optns.privateKey ? libVES.Algo.acquire(optns.privateKey).then(function(wc) {
1967
2107
  self.setField('algo',wc.engine.tag);
1968
2108
  if (!wc.privateKey) throw new libVES.Error('InvalidValue','Private key expected');
1969
2109
  return wc;
1970
- }) : (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() {
1971
2111
  return self.engine().then(function(e) {
1972
2112
  return e.generate(optns).then(function(ks) {
1973
2113
  ks.engine = e;
@@ -2113,6 +2253,14 @@ libVES.VaultKey.prototype = new libVES.Object({
2113
2253
  },
2114
2254
  matchVaults: function(vaultKeys) {
2115
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
+ });
2116
2264
  }
2117
2265
  });
2118
2266
 
@@ -2242,7 +2390,8 @@ libVES.VaultItem.prototype = new libVES.Object({
2242
2390
  });
2243
2391
  });
2244
2392
  }).then(function() {
2245
- 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);
2246
2395
  return self;
2247
2396
  });
2248
2397
  return self;
@@ -2298,6 +2447,12 @@ libVES.VaultItem.prototype = new libVES.Object({
2298
2447
  return rs;
2299
2448
  });
2300
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
+ });
2301
2456
  }
2302
2457
  });
2303
2458
  libVES.VaultItem.Type = {
@@ -2372,9 +2527,70 @@ libVES.External.prototype = new libVES.Object({
2372
2527
  }
2373
2528
  });
2374
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
+
2375
2590
  libVES.Algo = {
2376
2591
  ECDH: {
2377
2592
  tag: 'ECDH',
2593
+ defaultCurve: 'P-521',
2378
2594
  decrypt: function(k,buf) {
2379
2595
  var b = new Uint8Array(buf);
2380
2596
  var data = libVES.Util.ASN1.decode(b);
@@ -2398,7 +2614,12 @@ libVES.Algo = {
2398
2614
  return libVES.Algo.ECDH.eKey(k).then(function(eKey) {
2399
2615
  return libVES.Algo.ECDH.cipher(eKey.privateKey,k).then(function(ci) {
2400
2616
  return Promise.all([
2401
- 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
+ ),
2402
2623
  ci.encrypt(buf,true)
2403
2624
  ]).then(function(bufs) {
2404
2625
  var buf = new Uint8Array(bufs[0].byteLength + bufs[1].byteLength);
@@ -2413,21 +2634,32 @@ libVES.Algo = {
2413
2634
  });
2414
2635
  },
2415
2636
  eKey: function(pub) {
2416
- return crypto.subtle.exportKey('jwk',pub).then(function(kdata) {
2637
+ if (pub instanceof CryptoKey) return crypto.subtle.exportKey('jwk',pub).then(function(kdata) {
2417
2638
  return crypto.subtle.generateKey({name:'ECDH',namedCurve: kdata.crv},true,['deriveKey','deriveBits']).catch(function(e) {
2418
2639
  throw new libVES.Error('InvalidValue','Error generating ECIES ephemeral',{error: e});
2419
2640
  });
2420
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
+ });
2421
2657
  },
2422
- cipher: function(priv,pub) {
2658
+ cipher: function(priv, pub) {
2423
2659
  return libVES.getModule(libVES.Cipher,'AES256GCMp').then(function(m) {
2424
- return Promise.resolve(libVES.Algo.ECDH.curveBytes[pub.algorithm.namedCurve] || crypto.subtle.exportKey('jwk',pub).then(function(jwk) {
2425
- return jwk.x.length * 3 / 4;
2426
- })).then(function(len) {
2427
- return crypto.subtle.deriveBits({name:'ECDH',public:pub},priv,8 * len).then(function(raw) {
2428
- return crypto.subtle.digest({name:'SHA-384'},raw).then(function(buf) {
2429
- return new m(new Uint8Array(buf).slice(0,m.prototype.keySize + m.prototype.ivSize));
2430
- });
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));
2431
2663
  });
2432
2664
  });
2433
2665
  });
@@ -2462,13 +2694,22 @@ libVES.Algo = {
2462
2694
  }).then(function(der) {
2463
2695
  return libVES.Util.PEM.encode(der, 'PUBLIC KEY');
2464
2696
  });
2465
- }
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
+ });
2466
2700
  throw new libVES.Error('Internal', "Unknown type of key object");
2467
2701
  },
2468
2702
  generate: function(optns) {
2469
- var op = {name:'ECDH', namedCurve:'P-384'};
2703
+ var op = {name: 'ECDH', namedCurve: this.defaultCurve};
2470
2704
  if (optns) for (var k in optns) op[k] = optns[k];
2471
- 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
+ });
2472
2713
  },
2473
2714
  getPublic: function(priv) {
2474
2715
  return crypto.subtle.exportKey('jwk',priv).then(function(k) {
@@ -2481,7 +2722,48 @@ libVES.Algo = {
2481
2722
  y: k.y
2482
2723
  },{name:'ECDH'},true,[]);
2483
2724
  });
2484
- }
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'
2485
2767
  },
2486
2768
  RSA: {
2487
2769
  tag: 'RSA',
@@ -2540,7 +2822,7 @@ libVES.Algo = {
2540
2822
  throw new libVES.Error('Internal',"Unknown type of key object");
2541
2823
  },
2542
2824
  generate: function(optns) {
2543
- 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'};
2544
2826
  if (optns) for (var k in optns) op[k] = optns[k];
2545
2827
  return crypto.subtle.generateKey(op,true,['decrypt','encrypt']);
2546
2828
  },
@@ -2553,9 +2835,25 @@ libVES.Algo = {
2553
2835
  key_ops: ['encrypt'],
2554
2836
  kty: 'RSA',
2555
2837
  n: k.n
2556
- },{name:'RSA-OAEP',hash:'SHA-1'},true,['encrypt']);
2838
+ },{name:'RSA-OAEP',hash:'SHA-256'},true,['encrypt']);
2557
2839
  });
2558
- }
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
+ },
2559
2857
  },
2560
2858
  RSA_PKCS1_15: {
2561
2859
  tag: 'RSA_PKCS1_15',
@@ -2592,9 +2890,107 @@ libVES.Algo = {
2592
2890
  }
2593
2891
  });
2594
2892
  },
2893
+ fromKeyOptions: function(optns) {
2894
+ if (optns.namedCurve) return 'ECDH';
2895
+ if (optns.oqsAlgo) return 'OQS';
2896
+ if (optns.modulusLength) return 'RSA';
2897
+ },
2595
2898
  toString: function() {
2596
2899
  return 'libVES.Algo';
2597
- }
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/'
2598
2994
  };
2599
2995
 
2600
2996
  libVES.Cipher = function(data) {
@@ -3142,10 +3538,14 @@ libVES.Recovery.prototype = {
3142
3538
  return this.getMyToken().then(function(tkn) {
3143
3539
  if (!tkn) throw new libVES.Error('InvalidValue','No assistance available');
3144
3540
  return self.vaultKey.getUser().then(function(user) {
3145
- return tkn.vaultItem.shareWith(assist ? [tkn.user,user] : [tkn.user]).then(function() {
3146
- self.tokens = undefined;
3147
- self.vaultKey.vaultItems = undefined;
3148
- 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
+ });
3149
3549
  });
3150
3550
  });
3151
3551
  });
@@ -3394,7 +3794,7 @@ libVES.Flow.prototype.pubJWK = function(org) {
3394
3794
  return libVES.Flow.jwkPub(jwk);
3395
3795
  });
3396
3796
  }) : Promise.resolve(sessionStorage['VESflow|' + org]).then(function(k) {
3397
- 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);
3398
3798
  return JSON.parse(k);
3399
3799
  }));
3400
3800
  };
@@ -3421,7 +3821,7 @@ libVES.Flow.prototype.cipher = function(url) {
3421
3821
  libVES.Flow.prototype.encrypt = function(url, val) {
3422
3822
  var self = this;
3423
3823
  return Promise.resolve(val || this.value()).then(function(val) {
3424
- if (val == null) throw {code: 'NoData', message: 'Empty value'};
3824
+ if (val == null) throw new libVES.Error('NoData', 'Empty value');
3425
3825
  return self.cipher(url).then(function(ci) {
3426
3826
  var iv = new Uint8Array(12);
3427
3827
  crypto.getRandomValues(iv);
@@ -3512,7 +3912,7 @@ libVES.Flow.prototype.recv = function(dval) {
3512
3912
  tk = t;
3513
3913
  return true;
3514
3914
  });
3515
- 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');
3516
3916
  return Promise.resolve(self.source(src)).then(function() {
3517
3917
  if (dval) for (var k in dval) if (tk[k] === undefined) tk[k] = dval[k];
3518
3918
  return self.recvToken(tk);
@@ -3523,7 +3923,7 @@ libVES.Flow.prototype.recv = function(dval) {
3523
3923
  libVES.Flow.prototype.recvToken = function(tk) {
3524
3924
  var org = libVES.Flow.toOrigin(tk.url);
3525
3925
  if (org != this.origin && tk.key) sessionStorage['VESflow|' + org] = JSON.stringify(tk.key);
3526
- 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}));
3527
3927
  return this.decrypt(tk.enc, org);
3528
3928
  };
3529
3929
 
@@ -3538,7 +3938,7 @@ libVES.Flow.prototype.get = function() {
3538
3938
  self.url = document.location.href;
3539
3939
  return self.addToken(e.url).then(function(url) {
3540
3940
  document.location.replace(url);
3541
- throw {code: 'Reload', message: 'Completing the key exchange'};
3941
+ throw new libVES.Error('Redirect', 'Completing the key exchange');
3542
3942
  });
3543
3943
  }
3544
3944
  if (!data) throw e;
@@ -3552,13 +3952,13 @@ libVES.Flow.prototype.store = function(url) {
3552
3952
  this.sent = 1;
3553
3953
  return Promise.resolve(sessionStorage['VESflow.' + this.name + '>' + libVES.Flow.toOrigin(url)] = history.state['VESflow.' + this.name]);
3554
3954
  }
3555
- return Promise.reject({code: 'NotFound', message: 'Value is not set'});
3955
+ return Promise.reject(new libVES.Error('NotFound', 'Value is not set'));
3556
3956
  };
3557
3957
 
3558
3958
  libVES.Flow.prototype.fetch = function(url) {
3559
3959
  var self = this;
3560
3960
  return Promise.resolve(sessionStorage['VESflow.' + self.name + '>' + libVES.Flow.toOrigin(url)]).then(function(ctext) {
3561
- if (!ctext) throw {code: 'NotFound', message: 'Not in the session storage'};
3961
+ if (!ctext) throw new libVES.Error('NotFound', 'Not in the session storage');
3562
3962
  return self.decrypt(ctext).then(function(data) {
3563
3963
  self.erase(url);
3564
3964
  return data;
@@ -3678,19 +4078,16 @@ libVES.Auth.prototype.verify = function(token, auth) {
3678
4078
  libVES.Algo.OQS = {
3679
4079
  tag: 'OQS',
3680
4080
  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() {
4081
+ if (!this.wasmP) this.wasmP = (typeof(WasmOQS) == 'function' ? Promise.resolve()
4082
+ : libVES.Util.loadWasm(WasmOQSinit.baseUrl + 'WasmOQS.js')
4083
+ ).then(function() {
3690
4084
  return WasmOQS(WasmOQSinit);
3691
4085
  });
3692
4086
  return this.wasmP;
3693
4087
  },
4088
+ checkLimits: function(k) {
4089
+ return k.pub.byteLength + k.priv.byteLength <= libVES.maxKeyLen && k.ctextlen + 64 <= libVES.maxEncDataLen;
4090
+ },
3694
4091
  decrypt: function(k,buf) {
3695
4092
  return this.wasm().then(function(wasm) {
3696
4093
  var b = new Uint8Array(buf);
@@ -3737,56 +4134,54 @@ libVES.Algo.OQS = {
3737
4134
  },
3738
4135
  export: function(data, optns) {
3739
4136
  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
4137
  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');
4138
+ return libVES.Util.Key.export(data.pub, data.priv, oid, optns);
3753
4139
  },
3754
4140
  generate: function(optns) {
3755
- var algo = optns ? optns.algo : null;
4141
+ var algo = optns ? optns.oqsAlgo : null;
3756
4142
  if (!algo) algo = this.defaultAlgo;
3757
4143
  return this.wasm().then(function(wasm) {
3758
4144
  var k = wasm.init(algo, true);
3759
4145
  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 = {};
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);
3762
4149
  for (var i in k) if (i != 'priv') pub[i] = k[i];
3763
4150
  return {privateKey: k, publicKey: pub};
3764
4151
  });
3765
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
+ },
3766
4169
  Util: {
3767
4170
  import: function(args,chain,optns) {
3768
4171
  var algo = libVES.Util.ByteArrayToString(args);
3769
4172
  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;
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
+ });
3790
4185
  });
3791
4186
  });
3792
4187
  }
@@ -3794,59 +4189,76 @@ libVES.Algo.OQS = {
3794
4189
  OID: '1.3.6.1.4.1.53675.3.5',
3795
4190
  defaultAlgo: 'Kyber768'
3796
4191
  };
4192
+ libVES.Algo.all.push('OQS');
3797
4193
 
3798
4194
  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;
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;
3814
4213
  },
3815
4214
  generate: function(key) {
3816
- return this._WasmOQS_generate(key.ptr) >= 0;
4215
+ return this._WasmOQS_generate(key.ptr) >= 0;
3817
4216
  },
3818
4217
  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;
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;
3827
4226
  },
3828
4227
  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;
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;
3838
4238
  },
3839
4239
  free: function(key) {
3840
- this._WasmOQS_free(key.ptr);
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;
3841
4253
  },
3842
4254
  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);
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);
3850
4262
  },
3851
4263
  locateFile: function(file) {
3852
4264
  return this.baseUrl + file;
@@ -3854,4 +4266,133 @@ var WasmOQSinit = {
3854
4266
  baseUrl: 'https://ves.host/pub/'
3855
4267
  };
3856
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
+
3857
4398
  module.exports = libVES;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libves",
3
- "version": "2.6.0",
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.6.0.tgz DELETED
Binary file