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 +693 -152
- package/package.json +1 -1
- package/libves-2.6.0.tgz +0 -0
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.
|
|
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
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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:
|
|
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.
|
|
685
|
-
return
|
|
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
|
|
861
|
-
return
|
|
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
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
2425
|
-
return
|
|
2426
|
-
|
|
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:
|
|
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:
|
|
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-
|
|
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
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
3682
|
-
|
|
3683
|
-
|
|
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
|
-
|
|
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.
|
|
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 (!
|
|
3761
|
-
|
|
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
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
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
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
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
|
-
|
|
4215
|
+
return this._WasmOQS_generate(key.ptr) >= 0;
|
|
3817
4216
|
},
|
|
3818
4217
|
encaps: function(key) {
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
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
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
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
package/libves-2.6.0.tgz
DELETED
|
Binary file
|