use encrypt totp seeds with a master password

This commit is contained in:
Andris Reinman 2017-08-07 14:52:33 +03:00
parent 1def9f1e5e
commit c22612c869
2 changed files with 34 additions and 4 deletions

View file

@ -52,6 +52,10 @@ maxForwards=2000
# used to push outbound emails to the sending queue
#sender="zone-mta"
[totp]
cipher="aes192"
secret="a secret cat"
[attachments]
type="gridstore"
bucket="attachments"

View file

@ -622,11 +622,19 @@ class UserHandler {
if (!data.fresh && userData.seed) {
if (userData.seed) {
let secret = userData.seed;
if (userData.seed.charAt(0) === '$') {
let decipher = crypto.createDecipher(config.totp.cipher, config.totp.secret);
secret = decipher.update(userData.seed.substr(1), 'hex', 'utf-8');
secret += decipher.final('utf8');
}
let otpauth_url = speakeasy.otpauthURL({
secret: base32.decode(userData.seed),
secret: base32.decode(secret),
label: userData.username,
issuer: data.issuer || 'Wild Duck'
});
return QRCode.toDataURL(otpauth_url, (err, data_url) => {
if (err) {
log.error('DB', 'QRFAIL username=%s error=%s', userData.username, err.message);
@ -642,12 +650,16 @@ class UserHandler {
name: userData.username
});
let cipher = crypto.createCipher(config.totp.cipher, config.totp.secret);
let seed = '$' + cipher.update(secret.base32, 'utf8', 'hex');
seed += cipher.final('hex');
return this.users.collection('users').findOneAndUpdate({
_id: user,
enabled2fa: false
}, {
$set: {
seed: secret.base32
seed
}
}, {}, (err, result) => {
if (err) {
@ -714,8 +726,15 @@ class UserHandler {
return callback(err);
}
let secret = userData.seed;
if (userData.seed.charAt(0) === '$') {
let decipher = crypto.createDecipher(config.totp.cipher, config.totp.secret);
secret = decipher.update(userData.seed.substr(1), 'hex', 'utf-8');
secret += decipher.final('utf8');
}
let verified = speakeasy.totp.verify({
secret: userData.seed,
secret,
encoding: 'base32',
token: data.token,
window: 6
@ -819,8 +838,15 @@ class UserHandler {
return callback(err);
}
let secret = userData.seed;
if (userData.seed.charAt(0) === '$') {
let decipher = crypto.createDecipher(config.totp.cipher, config.totp.secret);
secret = decipher.update(userData.seed.substr(1), 'hex', 'utf-8');
secret += decipher.final('utf8');
}
let verified = speakeasy.totp.verify({
secret: userData.seed,
secret,
encoding: 'base32',
token: data.token,
window: 6