2014-10-02 16:05:44 -04:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var PrivateKeyDAO = function(restDao) {
|
|
|
|
this._restDao = restDao;
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// Device registration functions
|
|
|
|
//
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Request registration of a new device by fetching registration session key.
|
|
|
|
* @param {String} options.userId The user's email address
|
|
|
|
* @param {String} options.deviceName The device's memorable name
|
|
|
|
* @param {Function} callback(error, regSessionKey)
|
|
|
|
* @return {Object} {encryptedRegSessionKey:[base64]}
|
|
|
|
*/
|
|
|
|
PrivateKeyDAO.prototype.requestDeviceRegistration = function(options, callback) {
|
|
|
|
var uri;
|
|
|
|
|
|
|
|
if (!options.userId || !options.deviceName) {
|
|
|
|
callback(new Error('Incomplete arguments!'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uri = '/device/user/' + options.userId + '/devicename/' + options.deviceName;
|
|
|
|
this._restDao.post(undefined, uri, callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Authenticate device registration by uploading the deviceSecret encrypted with the regSessionKeys.
|
|
|
|
* @param {String} options.userId The user's email address
|
|
|
|
* @param {String} options.deviceName The device's memorable name
|
|
|
|
* @param {String} options.encryptedDeviceSecret The base64 encoded encrypted device secret
|
|
|
|
* @param {String} options.iv The iv used for encryption
|
|
|
|
* @param {Function} callback(error)
|
|
|
|
*/
|
|
|
|
PrivateKeyDAO.prototype.uploadDeviceSecret = function(options, callback) {
|
|
|
|
var uri;
|
|
|
|
|
|
|
|
if (!options.userId || !options.deviceName || !options.encryptedDeviceSecret || !options.iv) {
|
|
|
|
callback(new Error('Incomplete arguments!'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uri = '/device/user/' + options.userId + '/devicename/' + options.deviceName;
|
|
|
|
this._restDao.put(options, uri, callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// Private key functions
|
|
|
|
//
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Request authSessionKeys required for upload the encrypted private PGP key.
|
|
|
|
* @param {String} options.userId The user's email address
|
|
|
|
* @param {Function} callback(error, authSessionKey)
|
|
|
|
* @return {Object} {sessionId, encryptedAuthSessionKey:[base64 encoded], encryptedChallenge:[base64 encoded]}
|
|
|
|
*/
|
|
|
|
PrivateKeyDAO.prototype.requestAuthSessionKey = function(options, callback) {
|
|
|
|
var uri;
|
|
|
|
|
|
|
|
if (!options.userId) {
|
|
|
|
callback(new Error('Incomplete arguments!'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uri = '/auth/user/' + options.userId;
|
|
|
|
this._restDao.post(undefined, uri, callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Verifiy authentication by uploading the challenge and deviceSecret encrypted with the authSessionKeys as a response.
|
|
|
|
* @param {String} options.userId The user's email address
|
|
|
|
* @param {String} options.encryptedChallenge The server's base64 encoded challenge encrypted using the authSessionKey
|
|
|
|
* @param {String} options.encryptedDeviceSecret The server's base64 encoded deviceSecret encrypted using the authSessionKey
|
|
|
|
* @param {String} options.iv The iv used for encryption
|
|
|
|
* @param {Function} callback(error)
|
|
|
|
*/
|
|
|
|
PrivateKeyDAO.prototype.verifyAuthentication = function(options, callback) {
|
|
|
|
var uri;
|
|
|
|
|
|
|
|
if (!options.userId || !options.sessionId || !options.encryptedChallenge || !options.encryptedDeviceSecret || !options.iv) {
|
|
|
|
callback(new Error('Incomplete arguments!'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uri = '/auth/user/' + options.userId + '/session/' + options.sessionId;
|
|
|
|
this._restDao.put(options, uri, callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Upload the encrypted private PGP key.
|
|
|
|
* @param {String} options._id The hex encoded capital 16 char key id
|
|
|
|
* @param {String} options.userId The user's email address
|
|
|
|
* @param {String} options.encryptedPrivateKey The base64 encoded encrypted private PGP key
|
|
|
|
* @param {String} options.sessionId The session id
|
|
|
|
* @param {Function} callback(error)
|
|
|
|
*/
|
|
|
|
PrivateKeyDAO.prototype.upload = function(options, callback) {
|
|
|
|
var uri;
|
|
|
|
|
|
|
|
if (!options._id || !options.userId || !options.encryptedPrivateKey || !options.sessionId || !options.salt || !options.iv) {
|
|
|
|
callback(new Error('Incomplete arguments!'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uri = '/privatekey/user/' + options.userId + '/session/' + options.sessionId;
|
|
|
|
this._restDao.post(options, uri, callback);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Query if an encrypted private PGP key exists on the server without initializing the recovery procedure.
|
|
|
|
* @param {String} options.userId The user's email address
|
|
|
|
* @param {String} options.keyId The private PGP key id
|
|
|
|
* @param {Function} callback(error, found)
|
|
|
|
* @return {Boolean} whether the key was found on the server or not.
|
|
|
|
*/
|
|
|
|
PrivateKeyDAO.prototype.hasPrivateKey = function(options, callback) {
|
|
|
|
if (!options.userId || !options.keyId) {
|
|
|
|
callback(new Error('Incomplete arguments!'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._restDao.get({
|
|
|
|
uri: '/privatekey/user/' + options.userId + '/key/' + options.keyId + '?ignoreRecovery=true',
|
|
|
|
}, function(err) {
|
|
|
|
// 404: there is no encrypted private key on the server
|
|
|
|
if (err && err.code !== 200) {
|
|
|
|
callback(null, false);
|
2014-06-06 12:36:23 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
if (err) {
|
|
|
|
callback(err);
|
2014-06-06 12:36:23 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
callback(null, true);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Request download for the encrypted private PGP key.
|
|
|
|
* @param {String} options.userId The user's email address
|
|
|
|
* @param {String} options.keyId The private PGP key id
|
|
|
|
* @param {Function} callback(error, found)
|
|
|
|
* @return {Boolean} whether the key was found on the server or not.
|
|
|
|
*/
|
|
|
|
PrivateKeyDAO.prototype.requestDownload = function(options, callback) {
|
|
|
|
if (!options.userId || !options.keyId) {
|
|
|
|
callback(new Error('Incomplete arguments!'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._restDao.get({
|
|
|
|
uri: '/privatekey/user/' + options.userId + '/key/' + options.keyId
|
|
|
|
}, function(err) {
|
|
|
|
// 404: there is no encrypted private key on the server
|
|
|
|
if (err && err.code !== 200) {
|
|
|
|
callback(null, false);
|
2014-06-06 12:36:23 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
if (err) {
|
|
|
|
callback(err);
|
2014-06-06 12:36:23 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-02 16:05:44 -04:00
|
|
|
callback(null, true);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Verify the download request for the private PGP key using the recovery token sent via email. This downloads the actual encrypted private key.
|
|
|
|
* @param {String} options.userId The user's email address
|
|
|
|
* @param {String} options.keyId The private key id
|
|
|
|
* @param {String} options.recoveryToken The token proving the user own the email account
|
|
|
|
* @param {Function} callback(error, encryptedPrivateKey)
|
|
|
|
* @return {Object} {_id:[hex encoded capital 16 char key id], encryptedPrivateKey:[base64 encoded], encryptedUserId: [base64 encoded]}
|
|
|
|
*/
|
|
|
|
PrivateKeyDAO.prototype.download = function(options, callback) {
|
|
|
|
var uri;
|
|
|
|
|
|
|
|
if (!options.userId || !options.keyId || !options.recoveryToken) {
|
|
|
|
callback(new Error('Incomplete arguments!'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uri = '/privatekey/user/' + options.userId + '/key/' + options.keyId + '/recovery/' + options.recoveryToken;
|
|
|
|
this._restDao.get({
|
|
|
|
uri: uri
|
|
|
|
}, callback);
|
|
|
|
};
|
|
|
|
|
2014-10-08 06:34:34 -04:00
|
|
|
module.exports = PrivateKeyDAO;
|