"safe-buffer": "^5.0.1",
"scripty": "^1.5.0",
"sequelize": "^3.27.0",
- "ursa": "^0.9.1",
"winston": "^2.1.1",
"ws": "^1.1.1"
},
'use strict'
+const crypto = require('crypto')
const bcrypt = require('bcrypt')
const fs = require('fs')
const openssl = require('openssl-wrapper')
-const ursa = require('ursa')
const constants = require('../initializers/constants')
const logger = require('./logger')
sign
}
-function checkSignature (publicKey, rawData, hexSignature) {
- const crt = ursa.createPublicKey(publicKey)
- const isValid = crt.hashAndVerify('sha256', new Buffer(rawData).toString('hex'), hexSignature, 'hex')
+function checkSignature (publicKey, data, hexSignature) {
+ const verify = crypto.createVerify(constants.SIGNATURE_ALGORITHM)
+
+ let dataString
+ if (typeof data === 'string') {
+ dataString = data
+ } else {
+ try {
+ dataString = JSON.stringify(data)
+ } catch (err) {
+ logger.error('Cannot check signature.', { error: err })
+ return false
+ }
+ }
+
+ verify.update(dataString, 'utf8')
+
+ const isValid = verify.verify(publicKey, hexSignature, constants.SIGNATURE_ENCODING)
return isValid
}
+function sign (data) {
+ const sign = crypto.createSign(constants.SIGNATURE_ALGORITHM)
+
+ let dataString
+ if (typeof data === 'string') {
+ dataString = data
+ } else {
+ try {
+ dataString = JSON.stringify(data)
+ } catch (err) {
+ logger.error('Cannot sign data.', { error: err })
+ return ''
+ }
+ }
+
+ sign.update(dataString, 'utf8')
+
+ // TODO: make async
+ const myKey = fs.readFileSync(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem')
+ const signature = sign.sign(myKey, constants.SIGNATURE_ENCODING)
+
+ return signature
+}
+
function comparePassword (plainPassword, hashPassword, callback) {
bcrypt.compare(plainPassword, hashPassword, function (err, isPasswordMatch) {
if (err) return callback(err)
})
}
-function sign (data) {
- const myKey = ursa.createPrivateKey(fs.readFileSync(constants.CONFIG.STORAGE.CERT_DIR + 'peertube.key.pem'))
- const signature = myKey.hashAndSign('sha256', data, 'utf8', 'hex')
-
- return signature
-}
-
// ---------------------------------------------------------------------------
module.exports = peertubeCrypto
url: constants.REMOTE_SCHEME.HTTP + '://' + params.toPod.host + params.path
}
- // Add data with POST requst ?
- if (params.method === 'POST') {
- requestParams.json = {}
-
- // Add signature if it is specified in the params
- if (params.sign === true) {
- const host = constants.CONFIG.WEBSERVER.HOST
-
- requestParams.json.signature = {
- host,
- signature: peertubeCrypto.sign(host)
- }
- }
+ if (params.method !== 'POST') {
+ return callback(new Error('Cannot make a secure request with a non POST method.'))
+ }
+
+ requestParams.json = {}
- // If there are data informations
+ // Add signature if it is specified in the params
+ if (params.sign === true) {
+ const host = constants.CONFIG.WEBSERVER.HOST
+
+ let dataToSign
if (params.data) {
- requestParams.json.data = params.data
- request.post(requestParams, callback)
+ dataToSign = dataToSign = params.data
} else {
- // No data
- request.post(requestParams, callback)
+ // We do not have data to sign so we just take our host
+ // It is not ideal but the connection should be in HTTPS
+ dataToSign = host
}
- } else {
- request.get(requestParams, callback)
+
+ requestParams.json.signature = {
+ host, // Which host we pretend to be
+ signature: peertubeCrypto.sign(dataToSign)
+ }
+ }
+
+ // If there are data informations
+ if (params.data) {
+ requestParams.json.data = params.data
}
+
+ request.post(requestParams, callback)
}
// ---------------------------------------------------------------------------
VIDEOS: 'videos'
}
-// ---------------------------------------------------------------------------
-
const REMOTE_SCHEME = {
HTTP: 'https',
WS: 'wss'
}
+// ---------------------------------------------------------------------------
+
+const SIGNATURE_ALGORITHM = 'RSA-SHA256'
+const SIGNATURE_ENCODING = 'hex'
+
// Password encryption
const BCRYPT_SALT_SIZE = 10
+// ---------------------------------------------------------------------------
+
// Express static paths (router)
const STATIC_PATHS = {
PREVIEWS: '/static/previews/',
const THUMBNAILS_SIZE = '200x110'
const PREVIEWS_SIZE = '640x480'
+// ---------------------------------------------------------------------------
+
const USER_ROLES = {
ADMIN: 'admin',
USER: 'user'
REQUESTS_LIMIT,
RETRY_REQUESTS,
SEARCHABLE_COLUMNS,
+ SIGNATURE_ALGORITHM,
+ SIGNATURE_ENCODING,
SORTABLE_COLUMNS,
STATIC_MAX_AGE,
STATIC_PATHS,
logger.debug('Checking signature from %s.', host)
- const signatureOk = peertubeCrypto.checkSignature(pod.publicKey, host, req.body.signature.signature)
+ let signatureShouldBe
+ if (req.body.data) {
+ signatureShouldBe = req.body.data
+ } else {
+ signatureShouldBe = host
+ }
+
+ const signatureOk = peertubeCrypto.checkSignature(pod.publicKey, signatureShouldBe, req.body.signature.signature)
if (signatureOk === true) {
res.locals.secure = {
req.checkBody('signature.host', 'Should have a signature host').isURL()
req.checkBody('signature.signature', 'Should have a signature').notEmpty()
- logger.debug('Checking signature parameters', { parameters: { signatureHost: req.body.signature.host } })
+ logger.debug('Checking signature parameters', { parameters: { signature: req.body.signature } })
checkErrors(req, res, next)
}
'Error sending secure request to %s pod.',
toPod.host,
{
- error: err || new Error('Status code not 20x : ' + res.statusCode)
+ error: err ? err.message : 'Status code not 20x : ' + res.statusCode
}
)