From 1f22218b23f6ccd036836c9614e2b7f696268017 Mon Sep 17 00:00:00 2001 From: Koushik Dutta Date: Sun, 10 Dec 2023 09:21:40 -0800 Subject: [PATCH] server: recreate cert with valid date range on startup --- server/src/cert.ts | 22 +++++++++++++++------- server/src/scrypted-server-main.ts | 14 ++++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/server/src/cert.ts b/server/src/cert.ts index fb992b646a..0bcf58be84 100644 --- a/server/src/cert.ts +++ b/server/src/cert.ts @@ -7,12 +7,20 @@ const { pki } = forge; export const CURRENT_SELF_SIGNED_CERTIFICATE_VERSION = 'v2'; -export function createSelfSignedCertificate() { - - // generate a keypair and create an X.509v3 certificate - const keys = pki.rsa.generateKeyPair(2048); +export function createSelfSignedCertificate(serviceKey?: string) { + let privateKey: ReturnType; const cert = pki.createCertificate(); - cert.publicKey = keys.publicKey; + + if (serviceKey) { + privateKey = pki.privateKeyFromPem(serviceKey); + cert.publicKey = pki.rsa.setPublicKey(privateKey.n, privateKey.e); + } + else { + // generate a keypair and create an X.509v3 certificate + const keys = pki.rsa.generateKeyPair(2048); + privateKey = keys.privateKey; + cert.publicKey = keys.publicKey; + } // NOTE: serialNumber is the hex encoded value of an ASN.1 INTEGER. // Conforming CAs should ensure serialNumber is: @@ -65,9 +73,9 @@ export function createSelfSignedCertificate() { }]); // self-sign certificate - cert.sign(keys.privateKey); + cert.sign(privateKey); return { - serviceKey: pki.privateKeyToPem(keys.privateKey), + serviceKey: pki.privateKeyToPem(privateKey), certificate: pki.certificateToPem(cert), version: CURRENT_SELF_SIGNED_CERTIFICATE_VERSION, }; diff --git a/server/src/scrypted-server-main.ts b/server/src/scrypted-server-main.ts index f0d58c95e8..f77e91c854 100644 --- a/server/src/scrypted-server-main.ts +++ b/server/src/scrypted-server-main.ts @@ -124,15 +124,19 @@ async function start(mainFilename: string, options?: { await db.open(); let certSetting = await db.tryGet(Settings, 'certificate') as Settings; + let keyPair: ReturnType = certSetting?.value; if (certSetting?.value?.version !== CURRENT_SELF_SIGNED_CERTIFICATE_VERSION) { - const cert = createSelfSignedCertificate(); + keyPair = createSelfSignedCertificate(); certSetting = new Settings(); certSetting._id = 'certificate'; - certSetting.value = cert; + certSetting.value = keyPair; certSetting = await db.upsert(certSetting); } + else { + keyPair = createSelfSignedCertificate(keyPair.serviceKey); + } const basicAuth = httpAuth.basic({ realm: 'Scrypted', @@ -147,15 +151,13 @@ async function start(mainFilename: string, options?: { callback(sha === user.passwordHash || password === user.token); }); - const keys = certSetting.value; - const httpsServerOptions = process.env.SCRYPTED_HTTPS_OPTIONS_FILE ? JSON.parse(fs.readFileSync(process.env.SCRYPTED_HTTPS_OPTIONS_FILE).toString()) : {}; const mergedHttpsServerOptions = Object.assign({ - key: keys.serviceKey, - cert: keys.certificate + key: keyPair.serviceKey, + cert: keyPair.certificate }, httpsServerOptions); const secure = https.createServer(mergedHttpsServerOptions, app); const insecure = http.createServer(app);