From 5d7cb63ede7c4bba93954c0586f589ad9748d5ea Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 12 Jul 2022 10:54:21 +0200 Subject: [PATCH] Add compat with openssl 3 --- package.json | 4 +- server/helpers/core-utils.ts | 56 ++++++++++++++++-- .../custom-validators/activitypub/actor.ts | 4 +- server/helpers/peertube-crypto.ts | 9 +-- .../migrations/0605-actor-missing-keys.ts | 7 +-- yarn.lock | 58 ++----------------- 6 files changed, 65 insertions(+), 73 deletions(-) diff --git a/package.json b/package.json index 79bc7cf1f..bf83daa89 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "@opentelemetry/sdk-trace-node": "^1.3.1", "@opentelemetry/semantic-conventions": "^1.3.1", "@peertube/feed": "^5.0.1", - "@peertube/http-signature": "^1.6.0", + "@peertube/http-signature": "^1.7.0", "@uploadx/core": "^5.1.2", "async": "^3.0.1", "async-lru": "^1.1.1", @@ -151,7 +151,6 @@ "nodemailer": "^6.0.0", "parse-torrent": "^9.1.0", "password-generator": "^2.0.2", - "pem": "^1.12.3", "pg": "^8.2.1", "piscina": "^3.2.0", "prompt": "^1.0.0", @@ -206,7 +205,6 @@ "@types/node": "^14.14.31", "@types/nodemailer": "^6.2.0", "@types/oauth2-server": "^3.0.8", - "@types/pem": "^1.9.3", "@types/request": "^2.0.3", "@types/supertest": "^2.0.3", "@types/validator": "^13.0.0", 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 @@ */ import { exec, ExecOptions } from 'child_process' -import { randomBytes } from 'crypto' +import { ED25519KeyPairOptions, generateKeyPair, randomBytes, RSAKeyPairOptions } from 'crypto' import { truncate } from 'lodash' -import { createPrivateKey as createPrivateKey_1, getPublicKey as getPublicKey_1 } from 'pem' import { pipeline } from 'stream' import { URL } from 'url' import { promisify } from 'util' @@ -242,6 +241,51 @@ function toEven (num: number) { // --------------------------------------------------------------------------- +function generateRSAKeyPairPromise (size: number) { + return new Promise<{ publicKey: string, privateKey: string }>((res, rej) => { + const options: RSAKeyPairOptions<'pem', 'pem'> = { + modulusLength: size, + publicKeyEncoding: { + type: 'spki', + format: 'pem' + }, + privateKeyEncoding: { + type: 'pkcs1', + format: 'pem' + } + } + + generateKeyPair('rsa', options, (err, publicKey, privateKey) => { + if (err) return rej(err) + + return res({ publicKey, privateKey }) + }) + }) +} + +function generateED25519KeyPairPromise () { + return new Promise<{ publicKey: string, privateKey: string }>((res, rej) => { + const options: ED25519KeyPairOptions<'pem', 'pem'> = { + publicKeyEncoding: { + type: 'spki', + format: 'pem' + }, + privateKeyEncoding: { + type: 'pkcs8', + format: 'pem' + } + } + + generateKeyPair('ed25519', options, (err, publicKey, privateKey) => { + if (err) return rej(err) + + return res({ publicKey, privateKey }) + }) + }) +} + +// --------------------------------------------------------------------------- + function promisify0 (func: (cb: (err: any, result: A) => void) => void): () => Promise { return function promisified (): Promise { return new Promise((resolve: (arg: A) => void, reject: (err: any) => void) => { @@ -268,8 +312,6 @@ function promisify2 (func: (arg1: T, arg2: U, cb: (err: any, result: A) } const randomBytesPromise = promisify1(randomBytes) -const createPrivateKey = promisify1(createPrivateKey_1) -const getPublicKey = promisify1(getPublicKey_1) const execPromise2 = promisify2(exec) const execPromise = promisify1(exec) const pipelinePromise = promisify(pipeline) @@ -298,8 +340,10 @@ export { promisify2, randomBytesPromise, - createPrivateKey, - getPublicKey, + + generateRSAKeyPairPromise, + generateED25519KeyPairPromise, + execPromise2, execPromise, 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) { function isActorPrivateKeyValid (privateKey: string) { return exists(privateKey) && typeof privateKey === 'string' && - privateKey.startsWith('-----BEGIN RSA PRIVATE KEY-----') && + (privateKey.startsWith('-----BEGIN RSA PRIVATE KEY-----') || privateKey.startsWith('-----BEGIN PRIVATE KEY-----')) && // Sometimes there is a \n at the end, so just assert the string contains the end mark - privateKey.includes('-----END RSA PRIVATE KEY-----') && + (privateKey.includes('-----END RSA PRIVATE KEY-----') || privateKey.includes('-----END PRIVATE KEY-----')) && validator.isLength(privateKey, CONSTRAINTS_FIELDS.ACTORS.PRIVATE_KEY) } 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' import { sha256 } from '@shared/extra-utils' import { BCRYPT_SALT_SIZE, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants' import { MActor } from '../types/models' -import { createPrivateKey, getPublicKey, promisify1, promisify2 } from './core-utils' +import { generateRSAKeyPairPromise, promisify1, promisify2 } from './core-utils' import { jsonld } from './custom-jsonld-signature' import { logger } from './logger' @@ -15,13 +15,10 @@ const bcryptHashPromise = promisify2(hash) const httpSignature = require('@peertube/http-signature') -async function createPrivateAndPublicKeys () { +function createPrivateAndPublicKeys () { logger.info('Generating a RSA key...') - const { key } = await createPrivateKey(PRIVATE_RSA_KEY_SIZE) - const { publicKey } = await getPublicKey(key) - - return { privateKey: key, publicKey } + return generateRSAKeyPairPromise(PRIVATE_RSA_KEY_SIZE) } // 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 @@ import * as Sequelize from 'sequelize' -import { createPrivateKey, getPublicKey } from '../../helpers/core-utils' +import { generateRSAKeyPairPromise } from '../../helpers/core-utils' import { PRIVATE_RSA_KEY_SIZE } from '../constants' async function up (utils: { @@ -15,10 +15,9 @@ async function up (utils: { const actors = await utils.sequelize.query(query, options) for (const actor of actors) { - const { key } = await createPrivateKey(PRIVATE_RSA_KEY_SIZE) - const { publicKey } = await getPublicKey(key) + const { privateKey, publicKey } = await generateRSAKeyPairPromise(PRIVATE_RSA_KEY_SIZE) - const queryUpdate = `UPDATE "actor" SET "publicKey" = '${publicKey}', "privateKey" = '${key}' WHERE id = ${actor.id}` + const queryUpdate = `UPDATE "actor" SET "publicKey" = '${publicKey}', "privateKey" = '${privateKey}' WHERE id = ${actor.id}` await utils.sequelize.query(queryUpdate) } } diff --git a/yarn.lock b/yarn.lock index 530482b22..c02606375 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1780,10 +1780,10 @@ dependencies: xml-js "^1.6.11" -"@peertube/http-signature@^1.6.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@peertube/http-signature/-/http-signature-1.6.0.tgz#22bef028384e6437e8dbd94052ba7b8bd7f7f1ae" - integrity sha512-Bx780c7FPYtkV4LgCoaJcXYcKQqaMef2iQR2V2r5klkYkIQWFxbTOpyhKxvVXYIBIFpj5Cb8DGVDAmhkm7aavg== +"@peertube/http-signature@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@peertube/http-signature/-/http-signature-1.7.0.tgz#12a84f3fc62e786aa3a2eb09426417bad65736dc" + integrity sha512-aGQIwo6/sWtyyqhVK4e1MtxYz4N1X8CNt6SOtCc+Wnczs5S5ONaLHDDR8LYaGn0MgOwvGgXyuZ5sJIfd7iyoUw== dependencies: assert-plus "^1.0.0" jsprim "^1.2.2" @@ -2221,13 +2221,6 @@ "@types/node" "*" "@types/parse-torrent-file" "*" -"@types/pem@^1.9.3": - version "1.9.6" - resolved "https://registry.yarnpkg.com/@types/pem/-/pem-1.9.6.tgz#c3686832e935947fdd9d848dec3b8fe830068de7" - integrity sha512-IC67SxacM9fxEi/w7hf98dTun83OwUMeLMo1NS2gE0wdM9MHeg73iH/Pp9nB02OUCQ7Zb2UuKE/IpFCmQw9jxw== - dependencies: - "@types/node" "*" - "@types/pg-pool@2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/pg-pool/-/pg-pool-2.0.3.tgz#3eb8df2933f617f219a53091ad4080c94ba1c959" @@ -3332,11 +3325,6 @@ character-parser@^2.2.0: dependencies: is-regex "^1.0.3" -charenc@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" - integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== - charset-detector@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/charset-detector/-/charset-detector-0.0.2.tgz#1cd5ddaf56e83259c6ef8e906ccf06f75fe9a1b2" @@ -3778,11 +3766,6 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -crypt@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" - integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== - css-select@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" @@ -4314,11 +4297,6 @@ es6-iterator@^2.0.3: es5-ext "^0.10.35" es6-symbol "^3.1.1" -es6-promisify@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-6.1.1.tgz#46837651b7b06bf6fff893d03f29393668d01621" - integrity sha512-HBL8I3mIki5C1Cc9QjKUenHtnG0A5/xA8Q/AllRcfiwl2CZFXGK7ddBiCoRwAix4i2KxcQfjtIVcrVbB3vbmwg== - es6-symbol@^3.1.1, es6-symbol@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" @@ -5604,11 +5582,6 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-buffer@~1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" @@ -6348,15 +6321,6 @@ maxmind@^4.3.6: mmdb-lib "2.0.2" tiny-lru "8.0.2" -md5@^2.2.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f" - integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g== - dependencies: - charenc "0.0.2" - crypt "0.0.2" - is-buffer "~1.1.6" - mdurl@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" @@ -6988,7 +6952,7 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== @@ -7236,16 +7200,6 @@ peek-stream@^1.1.1: duplexify "^3.5.0" through2 "^2.0.3" -pem@^1.12.3: - version "1.14.6" - resolved "https://registry.yarnpkg.com/pem/-/pem-1.14.6.tgz#89babca3a73466fb844df70666dbf1b25eb0dc56" - integrity sha512-I5GKUer2PPv5qzUfxaZ6IGRkhp+357Kyv2t1JJg9vP8hGGI13qU34N2QupmggbpIZGPuudH0jn8KU5hjFpPk3g== - dependencies: - es6-promisify "^6.0.0" - md5 "^2.2.1" - os-tmpdir "^1.0.1" - which "^2.0.2" - pg-connection-string@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" @@ -9332,7 +9286,7 @@ which@^1.1.1: dependencies: isexe "^2.0.0" -which@^2.0.1, which@^2.0.2: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==