aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/helpers/core-utils.ts56
-rw-r--r--server/helpers/custom-validators/activitypub/actor.ts4
-rw-r--r--server/helpers/peertube-crypto.ts9
-rw-r--r--server/initializers/migrations/0605-actor-missing-keys.ts7
4 files changed, 58 insertions, 18 deletions
diff --git a/server/helpers/core-utils.ts b/server/helpers/core-utils.ts
index 4bbf0228d..c762f6a29 100644
--- a/server/helpers/core-utils.ts
+++ b/server/helpers/core-utils.ts
@@ -6,9 +6,8 @@
6*/ 6*/
7 7
8import { exec, ExecOptions } from 'child_process' 8import { exec, ExecOptions } from 'child_process'
9import { randomBytes } from 'crypto' 9import { ED25519KeyPairOptions, generateKeyPair, randomBytes, RSAKeyPairOptions } from 'crypto'
10import { truncate } from 'lodash' 10import { truncate } from 'lodash'
11import { createPrivateKey as createPrivateKey_1, getPublicKey as getPublicKey_1 } from 'pem'
12import { pipeline } from 'stream' 11import { pipeline } from 'stream'
13import { URL } from 'url' 12import { URL } from 'url'
14import { promisify } from 'util' 13import { promisify } from 'util'
@@ -242,6 +241,51 @@ function toEven (num: number) {
242 241
243// --------------------------------------------------------------------------- 242// ---------------------------------------------------------------------------
244 243
244function generateRSAKeyPairPromise (size: number) {
245 return new Promise<{ publicKey: string, privateKey: string }>((res, rej) => {
246 const options: RSAKeyPairOptions<'pem', 'pem'> = {
247 modulusLength: size,
248 publicKeyEncoding: {
249 type: 'spki',
250 format: 'pem'
251 },
252 privateKeyEncoding: {
253 type: 'pkcs1',
254 format: 'pem'
255 }
256 }
257
258 generateKeyPair('rsa', options, (err, publicKey, privateKey) => {
259 if (err) return rej(err)
260
261 return res({ publicKey, privateKey })
262 })
263 })
264}
265
266function generateED25519KeyPairPromise () {
267 return new Promise<{ publicKey: string, privateKey: string }>((res, rej) => {
268 const options: ED25519KeyPairOptions<'pem', 'pem'> = {
269 publicKeyEncoding: {
270 type: 'spki',
271 format: 'pem'
272 },
273 privateKeyEncoding: {
274 type: 'pkcs8',
275 format: 'pem'
276 }
277 }
278
279 generateKeyPair('ed25519', options, (err, publicKey, privateKey) => {
280 if (err) return rej(err)
281
282 return res({ publicKey, privateKey })
283 })
284 })
285}
286
287// ---------------------------------------------------------------------------
288
245function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> { 289function promisify0<A> (func: (cb: (err: any, result: A) => void) => void): () => Promise<A> {
246 return function promisified (): Promise<A> { 290 return function promisified (): Promise<A> {
247 return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => { 291 return new Promise<A>((resolve: (arg: A) => void, reject: (err: any) => void) => {
@@ -268,8 +312,6 @@ function promisify2<T, U, A> (func: (arg1: T, arg2: U, cb: (err: any, result: A)
268} 312}
269 313
270const randomBytesPromise = promisify1<number, Buffer>(randomBytes) 314const randomBytesPromise = promisify1<number, Buffer>(randomBytes)
271const createPrivateKey = promisify1<number, { key: string }>(createPrivateKey_1)
272const getPublicKey = promisify1<string, { publicKey: string }>(getPublicKey_1)
273const execPromise2 = promisify2<string, any, string>(exec) 315const execPromise2 = promisify2<string, any, string>(exec)
274const execPromise = promisify1<string, string>(exec) 316const execPromise = promisify1<string, string>(exec)
275const pipelinePromise = promisify(pipeline) 317const pipelinePromise = promisify(pipeline)
@@ -298,8 +340,10 @@ export {
298 promisify2, 340 promisify2,
299 341
300 randomBytesPromise, 342 randomBytesPromise,
301 createPrivateKey, 343
302 getPublicKey, 344 generateRSAKeyPairPromise,
345 generateED25519KeyPairPromise,
346
303 execPromise2, 347 execPromise2,
304 execPromise, 348 execPromise,
305 pipelinePromise, 349 pipelinePromise,
diff --git a/server/helpers/custom-validators/activitypub/actor.ts b/server/helpers/custom-validators/activitypub/actor.ts
index a4b152722..f43c35b23 100644
--- a/server/helpers/custom-validators/activitypub/actor.ts
+++ b/server/helpers/custom-validators/activitypub/actor.ts
@@ -41,9 +41,9 @@ function isActorPreferredUsernameValid (preferredUsername: string) {
41function isActorPrivateKeyValid (privateKey: string) { 41function isActorPrivateKeyValid (privateKey: string) {
42 return exists(privateKey) && 42 return exists(privateKey) &&
43 typeof privateKey === 'string' && 43 typeof privateKey === 'string' &&
44 privateKey.startsWith('-----BEGIN RSA PRIVATE KEY-----') && 44 (privateKey.startsWith('-----BEGIN RSA PRIVATE KEY-----') || privateKey.startsWith('-----BEGIN PRIVATE KEY-----')) &&
45 // Sometimes there is a \n at the end, so just assert the string contains the end mark 45 // Sometimes there is a \n at the end, so just assert the string contains the end mark
46 privateKey.includes('-----END RSA PRIVATE KEY-----') && 46 (privateKey.includes('-----END RSA PRIVATE KEY-----') || privateKey.includes('-----END PRIVATE KEY-----')) &&
47 validator.isLength(privateKey, CONSTRAINTS_FIELDS.ACTORS.PRIVATE_KEY) 47 validator.isLength(privateKey, CONSTRAINTS_FIELDS.ACTORS.PRIVATE_KEY)
48} 48}
49 49
diff --git a/server/helpers/peertube-crypto.ts b/server/helpers/peertube-crypto.ts
index 1a7ee24a7..1d9cab2ce 100644
--- a/server/helpers/peertube-crypto.ts
+++ b/server/helpers/peertube-crypto.ts
@@ -5,7 +5,7 @@ import { cloneDeep } from 'lodash'
5import { sha256 } from '@shared/extra-utils' 5import { sha256 } from '@shared/extra-utils'
6import { BCRYPT_SALT_SIZE, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants' 6import { BCRYPT_SALT_SIZE, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants'
7import { MActor } from '../types/models' 7import { MActor } from '../types/models'
8import { createPrivateKey, getPublicKey, promisify1, promisify2 } from './core-utils' 8import { generateRSAKeyPairPromise, promisify1, promisify2 } from './core-utils'
9import { jsonld } from './custom-jsonld-signature' 9import { jsonld } from './custom-jsonld-signature'
10import { logger } from './logger' 10import { logger } from './logger'
11 11
@@ -15,13 +15,10 @@ const bcryptHashPromise = promisify2<any, string | number, string>(hash)
15 15
16const httpSignature = require('@peertube/http-signature') 16const httpSignature = require('@peertube/http-signature')
17 17
18async function createPrivateAndPublicKeys () { 18function createPrivateAndPublicKeys () {
19 logger.info('Generating a RSA key...') 19 logger.info('Generating a RSA key...')
20 20
21 const { key } = await createPrivateKey(PRIVATE_RSA_KEY_SIZE) 21 return generateRSAKeyPairPromise(PRIVATE_RSA_KEY_SIZE)
22 const { publicKey } = await getPublicKey(key)
23
24 return { privateKey: key, publicKey }
25} 22}
26 23
27// User password checks 24// User password checks
diff --git a/server/initializers/migrations/0605-actor-missing-keys.ts b/server/initializers/migrations/0605-actor-missing-keys.ts
index 72d9b359d..aa89a500c 100644
--- a/server/initializers/migrations/0605-actor-missing-keys.ts
+++ b/server/initializers/migrations/0605-actor-missing-keys.ts
@@ -1,5 +1,5 @@
1import * as Sequelize from 'sequelize' 1import * as Sequelize from 'sequelize'
2import { createPrivateKey, getPublicKey } from '../../helpers/core-utils' 2import { generateRSAKeyPairPromise } from '../../helpers/core-utils'
3import { PRIVATE_RSA_KEY_SIZE } from '../constants' 3import { PRIVATE_RSA_KEY_SIZE } from '../constants'
4 4
5async function up (utils: { 5async function up (utils: {
@@ -15,10 +15,9 @@ async function up (utils: {
15 const actors = await utils.sequelize.query<any>(query, options) 15 const actors = await utils.sequelize.query<any>(query, options)
16 16
17 for (const actor of actors) { 17 for (const actor of actors) {
18 const { key } = await createPrivateKey(PRIVATE_RSA_KEY_SIZE) 18 const { privateKey, publicKey } = await generateRSAKeyPairPromise(PRIVATE_RSA_KEY_SIZE)
19 const { publicKey } = await getPublicKey(key)
20 19
21 const queryUpdate = `UPDATE "actor" SET "publicKey" = '${publicKey}', "privateKey" = '${key}' WHERE id = ${actor.id}` 20 const queryUpdate = `UPDATE "actor" SET "publicKey" = '${publicKey}', "privateKey" = '${privateKey}' WHERE id = ${actor.id}`
22 await utils.sequelize.query(queryUpdate) 21 await utils.sequelize.query(queryUpdate)
23 } 22 }
24 } 23 }