/
utils.js
157 lines (123 loc) · 4.63 KB
/
utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
var rsa = require("node-rsa")
var aes = require('aes-js')
var pbkdf2 = require('pbkdf2/browser')
var hours = 1000*60*60
var keyCache; // keeps the derived key in memory for the user specified time
var groupsCache; // keeps the plaintext groups in memory very temporarily (for performance reasons)
var utils = exports
try {
var createProofWorker = new Worker("createProofWorker.js")
} catch(e) {
if(!(e instanceof ReferenceError)) throw e
// ignore ReferenceError - Worker won't be defined inside a worker
}
exports.changePassword = function(oldPassword, newPassword) {
var groups = getGroups(oldPassword)
localStorage.setItem("salt", createRandomString(128))
localStorage.setItem("key", JSON.stringify({derived: getKey(newPassword), expires:Date.now()+24*7*hours}))
saveGroups(groups, newPassword)
}
var getGroups = exports.getGroups = function(password) {
if(groupsCache === undefined) {
var groups = localStorage.getItem("groups")
if(groups === null) {
groupsCache = []
} else {
var key = getKey(password)
var decryptedGroups = aesDecrypt(key, groups)
groupsCache = JSON.parse(decryptedGroups)
}
setTimeout(function() {
groupsCache = undefined // clear the groups from memory as soon as possible
},500)
}
return groupsCache
}
exports.createNewGroup = function(name, email, password, autoAuth) {
var pair = new rsa({b: 512, environment: 'browser'});
var groups = getGroups(password)
var id = Date.now()+createRandomString(5)
var group = {id: id, name:name, email:email, autoAuth: autoAuth, keyPair: pair.exportKey('pkcs8')}
groups.push(group)
saveGroups(groups, password)
return group
}
exports.createProof = function(keyPair, origin, token) {
var pair = new rsa({environment: 'browser'})
pair.importKey(keyPair, 'pkcs8')
return pair.sign(token,'base64','utf8')
}
exports.createProofWorker = function(keyPair, origin, token, callback) {
createProofWorker.onmessage = function(result) {
callback(undefined, result)
}
createProofWorker.postMessage([keyPair, origin, token])
}
exports.acceptAuthRequest = function(origin, group, token, password, callback) {
var start = Date.now()
if(group === undefined) {
group = utils.createNewGroup('primary', 'me@me.me', password, true)
localStorage.setItem(origin, group.id)
}
utils.createProofWorker(group.keyPair, origin, token, function(err, proof) {
alert("took: "+(Date.now()-start)+'ms')
callback(err, {response:'auth', proof:proof})
})
}
// returns the group for the passed origin
var getGroup = exports.getGroup = function(origin,password) {
var groupId = localStorage.getItem(origin)
var groups = getGroups(password)
for(var n=0; n<groups.length; n++) {
if(groups[n].id === groupId)
return groups[n]
}
}
function createRandomString(length) {
var possible = 122-48
var chars = []
for(var n=0; n<length; n++) {
chars.push(String.fromCharCode(Math.floor(Math.random() * possible)+48))
}
return chars.join('')
}
function saveGroups(groups, password) {
var key = getKey(password)
var encryptedGroups = aesEncrypt(key, JSON.stringify(groups))
localStorage.setItem("groups", encryptedGroups)
}
function aesEncrypt(key, text) {
var textBytes = aes.util.convertStringToBytes(text)
var encryptedBytes = new aes.ModeOfOperation.ctr(key).encrypt(textBytes)
return encryptedBytes.toString('base64')
}
function aesDecrypt(key, encryptedText) {
var encryptedBytes = new Buffer(encryptedText,'base64')
var decryptedBytes = new aes.ModeOfOperation.ctr(key).decrypt(encryptedBytes)
return aes.util.convertBytesToString(decryptedBytes);
}
function createKey(salt, password) {
return pbkdf2.pbkdf2Sync(password, salt, 5, 256 / 8, 'sha512')
}
function getKey(password) {
var key = localStorage.getItem("key")
if(key !== null) {
var key = JSON.parse(key)
}
if(key === null || key.expires < Date.now()) {
if(password === undefined)
throw new Error("passwordNeeded")
var salt = localStorage.getItem("salt")
key = {derived:createKey(salt, password),expires:Date.now()+24*7*hours}
localStorage.setItem("key", JSON.stringify(key))
}
return key.derived
}
//var proof = exports.createProof(origin, token)
//console.log(proof)
//
// var group = getGroup(origin, password)
// var pair = new rsa({environment: 'browser'})
// pair.importKey(group.keyPair, 'pkcs8')
// var x=pair.verify(token,proof,'utf8', 'base64')
// console.log(x)