Encrypts data with a public key

@param {String} publicKeyDataOrFile - Either the public key, or the full path to
a file containing the public key
@param {String} data                - String version of the data to encrypt

@returns {Promise} A promise which is resolved with a base64 encoded version
of the encrypted data, or rejected if an error occurs.
function encrypt(publicKeyDataOrFile, data) {
        const deferred = q.defer();
        let publicKeyPromise;

        const getPublicKey = function getPublicKey(publicKeyFile) {
            const publicKeyDeferred = q.defer();
            fs.readFile(publicKeyFile, (err, publicKey) => {
                if (err) {
                    logger.warn('Error reading public key:', err);
                    publicKeyDeferred.reject(err);
                } else {
                    publicKeyDeferred.resolve(publicKey);
                }
            });

            return publicKeyDeferred.promise;
        };

        if (typeof data !== 'string') {
            deferred.reject(new Error('data must be a string'));
            return deferred.promise;
        }

        if (publicKeyDataOrFile.startsWith('-----BEGIN PUBLIC KEY-----')) {
            publicKeyPromise = q(publicKeyDataOrFile);
        } else {
            publicKeyPromise = getPublicKey(publicKeyDataOrFile);
        }

        publicKeyPromise
            .then((publicKey) => {
                let encrypted;

                try {
                    encrypted = crypto.publicEncrypt(publicKey, util.createBufferFrom(data));
                    deferred.resolve(encrypted.toString('base64'));
                } catch (err) {
                    logger.warn('Error encrypting data:', err);
                    deferred.reject(err);
                }
            })
            .catch((err) => {
                logger.warn('Unable to get public key:', err);
                deferred.reject(err);
            });

        return deferred.promise;
    }