From 41f2ebae4f970932fb62d2d8923b1f776f0b1494 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 19 Oct 2018 11:41:19 +0200 Subject: Add HTTP signature check before linked signature It's faster, and will allow us to use RSA signature 2018 (with upstream jsonld-signature module) without too much incompatibilities in the peertube federation --- server/helpers/activitypub.ts | 32 +++++++++--------- server/helpers/peertube-crypto.ts | 70 ++++++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 39 deletions(-) (limited to 'server/helpers') diff --git a/server/helpers/activitypub.ts b/server/helpers/activitypub.ts index 1304c7559..278010e78 100644 --- a/server/helpers/activitypub.ts +++ b/server/helpers/activitypub.ts @@ -4,7 +4,7 @@ import { ResultList } from '../../shared/models' import { Activity, ActivityPubActor } from '../../shared/models/activitypub' import { ACTIVITY_PUB } from '../initializers' import { ActorModel } from '../models/activitypub/actor' -import { signObject } from './peertube-crypto' +import { signJsonLDObject } from './peertube-crypto' import { pageToStartAndCount } from './core-utils' function activityPubContextify (data: T) { @@ -15,22 +15,22 @@ function activityPubContextify (data: T) { { RsaSignature2017: 'https://w3id.org/security#RsaSignature2017', pt: 'https://joinpeertube.org/ns', - schema: 'http://schema.org#', + sc: 'http://schema.org#', Hashtag: 'as:Hashtag', - uuid: 'schema:identifier', - category: 'schema:category', - licence: 'schema:license', - subtitleLanguage: 'schema:subtitleLanguage', + uuid: 'sc:identifier', + category: 'sc:category', + licence: 'sc:license', + subtitleLanguage: 'sc:subtitleLanguage', sensitive: 'as:sensitive', - language: 'schema:inLanguage', - views: 'schema:Number', - stats: 'schema:Number', - size: 'schema:Number', - fps: 'schema:Number', - commentsEnabled: 'schema:Boolean', - waitTranscoding: 'schema:Boolean', - expires: 'schema:expires', - support: 'schema:Text', + language: 'sc:inLanguage', + views: 'sc:Number', + stats: 'sc:Number', + size: 'sc:Number', + fps: 'sc:Number', + commentsEnabled: 'sc:Boolean', + waitTranscoding: 'sc:Boolean', + expires: 'sc:expires', + support: 'sc:Text', CacheFile: 'pt:CacheFile' }, { @@ -102,7 +102,7 @@ async function activityPubCollectionPagination (url: string, handler: ActivityPu function buildSignedActivity (byActor: ActorModel, data: Object) { const activity = activityPubContextify(data) - return signObject(byActor, activity) as Promise + return signJsonLDObject(byActor, activity) as Promise } function getActorUrl (activityActor: string | ActivityPubActor) { diff --git a/server/helpers/peertube-crypto.ts b/server/helpers/peertube-crypto.ts index 5c182961d..cb5f27240 100644 --- a/server/helpers/peertube-crypto.ts +++ b/server/helpers/peertube-crypto.ts @@ -1,9 +1,12 @@ -import { BCRYPT_SALT_SIZE, PRIVATE_RSA_KEY_SIZE } from '../initializers' +import { Request } from 'express' +import { BCRYPT_SALT_SIZE, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers' import { ActorModel } from '../models/activitypub/actor' import { bcryptComparePromise, bcryptGenSaltPromise, bcryptHashPromise, createPrivateKey, getPublicKey } from './core-utils' import { jsig } from './custom-jsonld-signature' import { logger } from './logger' +const httpSignature = require('http-signature') + async function createPrivateAndPublicKeys () { logger.info('Generating a RSA key...') @@ -13,18 +16,42 @@ async function createPrivateAndPublicKeys () { return { privateKey: key, publicKey } } -function isSignatureVerified (fromActor: ActorModel, signedDocument: object) { +// User password checks + +function comparePassword (plainPassword: string, hashPassword: string) { + return bcryptComparePromise(plainPassword, hashPassword) +} + +async function cryptPassword (password: string) { + const salt = await bcryptGenSaltPromise(BCRYPT_SALT_SIZE) + + return bcryptHashPromise(password, salt) +} + +// HTTP Signature + +function isHTTPSignatureVerified (httpSignatureParsed: any, actor: ActorModel) { + return httpSignature.verifySignature(httpSignatureParsed, actor.publicKey) === true +} + +function parseHTTPSignature (req: Request) { + return httpSignature.parse(req, { authorizationHeaderName: HTTP_SIGNATURE.HEADER_NAME }) +} + +// JSONLD + +function isJsonLDSignatureVerified (fromActor: ActorModel, signedDocument: any) { const publicKeyObject = { '@context': jsig.SECURITY_CONTEXT_URL, - '@id': fromActor.url, - '@type': 'CryptographicKey', + id: fromActor.url, + type: 'CryptographicKey', owner: fromActor.url, publicKeyPem: fromActor.publicKey } const publicKeyOwnerObject = { '@context': jsig.SECURITY_CONTEXT_URL, - '@id': fromActor.url, + id: fromActor.url, publicKey: [ publicKeyObject ] } @@ -33,14 +60,19 @@ function isSignatureVerified (fromActor: ActorModel, signedDocument: object) { publicKeyOwner: publicKeyOwnerObject } - return jsig.promises.verify(signedDocument, options) - .catch(err => { - logger.error('Cannot check signature.', { err }) - return false - }) + return jsig.promises + .verify(signedDocument, options) + .then((result: { verified: boolean }) => { + logger.info('coucou', result) + return result.verified + }) + .catch(err => { + logger.error('Cannot check signature.', { err }) + return false + }) } -function signObject (byActor: ActorModel, data: any) { +function signJsonLDObject (byActor: ActorModel, data: any) { const options = { privateKeyPem: byActor.privateKey, creator: byActor.url, @@ -50,22 +82,14 @@ function signObject (byActor: ActorModel, data: any) { return jsig.promises.sign(data, options) } -function comparePassword (plainPassword: string, hashPassword: string) { - return bcryptComparePromise(plainPassword, hashPassword) -} - -async function cryptPassword (password: string) { - const salt = await bcryptGenSaltPromise(BCRYPT_SALT_SIZE) - - return bcryptHashPromise(password, salt) -} - // --------------------------------------------------------------------------- export { - isSignatureVerified, + parseHTTPSignature, + isHTTPSignatureVerified, + isJsonLDSignatureVerified, comparePassword, createPrivateAndPublicKeys, cryptPassword, - signObject + signJsonLDObject } -- cgit v1.2.3