diff options
author | Chocobozzz <me@florianbigard.com> | 2022-10-10 11:19:58 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-10-10 11:19:58 +0200 |
commit | 63fa260a81a8930c157b73c897fe8696a8cc90d4 (patch) | |
tree | 705ebfae42f9c59b2a1ac97779e4037102dfed1c /server/helpers/peertube-crypto.ts | |
parent | 9b99d32804e99462c6f22df3ec3db9ec5bf8a18c (diff) | |
parent | 1ea868a9456439108fbd87255537093ed8bd456f (diff) | |
download | PeerTube-63fa260a81a8930c157b73c897fe8696a8cc90d4.tar.gz PeerTube-63fa260a81a8930c157b73c897fe8696a8cc90d4.tar.zst PeerTube-63fa260a81a8930c157b73c897fe8696a8cc90d4.zip |
Merge branch 'feature/otp' into develop
Diffstat (limited to 'server/helpers/peertube-crypto.ts')
-rw-r--r-- | server/helpers/peertube-crypto.ts | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/server/helpers/peertube-crypto.ts b/server/helpers/peertube-crypto.ts index 8aca50900..ae7d11800 100644 --- a/server/helpers/peertube-crypto.ts +++ b/server/helpers/peertube-crypto.ts | |||
@@ -1,11 +1,11 @@ | |||
1 | import { compare, genSalt, hash } from 'bcrypt' | 1 | import { compare, genSalt, hash } from 'bcrypt' |
2 | import { createSign, createVerify } from 'crypto' | 2 | import { createCipheriv, createDecipheriv, createSign, createVerify } from 'crypto' |
3 | import { Request } from 'express' | 3 | import { Request } from 'express' |
4 | import { cloneDeep } from 'lodash' | 4 | import { cloneDeep } from 'lodash' |
5 | import { sha256 } from '@shared/extra-utils' | 5 | import { sha256 } from '@shared/extra-utils' |
6 | import { BCRYPT_SALT_SIZE, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants' | 6 | import { BCRYPT_SALT_SIZE, ENCRYPTION, HTTP_SIGNATURE, PRIVATE_RSA_KEY_SIZE } from '../initializers/constants' |
7 | import { MActor } from '../types/models' | 7 | import { MActor } from '../types/models' |
8 | import { generateRSAKeyPairPromise, promisify1, promisify2 } from './core-utils' | 8 | import { generateRSAKeyPairPromise, promisify1, promisify2, randomBytesPromise, scryptPromise } from './core-utils' |
9 | import { jsonld } from './custom-jsonld-signature' | 9 | import { jsonld } from './custom-jsonld-signature' |
10 | import { logger } from './logger' | 10 | import { logger } from './logger' |
11 | 11 | ||
@@ -21,9 +21,13 @@ function createPrivateAndPublicKeys () { | |||
21 | return generateRSAKeyPairPromise(PRIVATE_RSA_KEY_SIZE) | 21 | return generateRSAKeyPairPromise(PRIVATE_RSA_KEY_SIZE) |
22 | } | 22 | } |
23 | 23 | ||
24 | // --------------------------------------------------------------------------- | ||
24 | // User password checks | 25 | // User password checks |
26 | // --------------------------------------------------------------------------- | ||
25 | 27 | ||
26 | function comparePassword (plainPassword: string, hashPassword: string) { | 28 | function comparePassword (plainPassword: string, hashPassword: string) { |
29 | if (!plainPassword) return Promise.resolve(false) | ||
30 | |||
27 | return bcryptComparePromise(plainPassword, hashPassword) | 31 | return bcryptComparePromise(plainPassword, hashPassword) |
28 | } | 32 | } |
29 | 33 | ||
@@ -33,7 +37,9 @@ async function cryptPassword (password: string) { | |||
33 | return bcryptHashPromise(password, salt) | 37 | return bcryptHashPromise(password, salt) |
34 | } | 38 | } |
35 | 39 | ||
40 | // --------------------------------------------------------------------------- | ||
36 | // HTTP Signature | 41 | // HTTP Signature |
42 | // --------------------------------------------------------------------------- | ||
37 | 43 | ||
38 | function isHTTPSignatureDigestValid (rawBody: Buffer, req: Request): boolean { | 44 | function isHTTPSignatureDigestValid (rawBody: Buffer, req: Request): boolean { |
39 | if (req.headers[HTTP_SIGNATURE.HEADER_NAME] && req.headers['digest']) { | 45 | if (req.headers[HTTP_SIGNATURE.HEADER_NAME] && req.headers['digest']) { |
@@ -62,7 +68,9 @@ function parseHTTPSignature (req: Request, clockSkew?: number) { | |||
62 | return parsed | 68 | return parsed |
63 | } | 69 | } |
64 | 70 | ||
71 | // --------------------------------------------------------------------------- | ||
65 | // JSONLD | 72 | // JSONLD |
73 | // --------------------------------------------------------------------------- | ||
66 | 74 | ||
67 | function isJsonLDSignatureVerified (fromActor: MActor, signedDocument: any): Promise<boolean> { | 75 | function isJsonLDSignatureVerified (fromActor: MActor, signedDocument: any): Promise<boolean> { |
68 | if (signedDocument.signature.type === 'RsaSignature2017') { | 76 | if (signedDocument.signature.type === 'RsaSignature2017') { |
@@ -112,6 +120,8 @@ async function signJsonLDObject <T> (byActor: MActor, data: T) { | |||
112 | return Object.assign(data, { signature }) | 120 | return Object.assign(data, { signature }) |
113 | } | 121 | } |
114 | 122 | ||
123 | // --------------------------------------------------------------------------- | ||
124 | |||
115 | function buildDigest (body: any) { | 125 | function buildDigest (body: any) { |
116 | const rawBody = typeof body === 'string' ? body : JSON.stringify(body) | 126 | const rawBody = typeof body === 'string' ? body : JSON.stringify(body) |
117 | 127 | ||
@@ -119,6 +129,34 @@ function buildDigest (body: any) { | |||
119 | } | 129 | } |
120 | 130 | ||
121 | // --------------------------------------------------------------------------- | 131 | // --------------------------------------------------------------------------- |
132 | // Encryption | ||
133 | // --------------------------------------------------------------------------- | ||
134 | |||
135 | async function encrypt (str: string, secret: string) { | ||
136 | const iv = await randomBytesPromise(ENCRYPTION.IV) | ||
137 | |||
138 | const key = await scryptPromise(secret, ENCRYPTION.SALT, 32) | ||
139 | const cipher = createCipheriv(ENCRYPTION.ALGORITHM, key, iv) | ||
140 | |||
141 | let encrypted = iv.toString(ENCRYPTION.ENCODING) + ':' | ||
142 | encrypted += cipher.update(str, 'utf8', ENCRYPTION.ENCODING) | ||
143 | encrypted += cipher.final(ENCRYPTION.ENCODING) | ||
144 | |||
145 | return encrypted | ||
146 | } | ||
147 | |||
148 | async function decrypt (encryptedArg: string, secret: string) { | ||
149 | const [ ivStr, encryptedStr ] = encryptedArg.split(':') | ||
150 | |||
151 | const iv = Buffer.from(ivStr, 'hex') | ||
152 | const key = await scryptPromise(secret, ENCRYPTION.SALT, 32) | ||
153 | |||
154 | const decipher = createDecipheriv(ENCRYPTION.ALGORITHM, key, iv) | ||
155 | |||
156 | return decipher.update(encryptedStr, ENCRYPTION.ENCODING, 'utf8') + decipher.final('utf8') | ||
157 | } | ||
158 | |||
159 | // --------------------------------------------------------------------------- | ||
122 | 160 | ||
123 | export { | 161 | export { |
124 | isHTTPSignatureDigestValid, | 162 | isHTTPSignatureDigestValid, |
@@ -129,7 +167,10 @@ export { | |||
129 | comparePassword, | 167 | comparePassword, |
130 | createPrivateAndPublicKeys, | 168 | createPrivateAndPublicKeys, |
131 | cryptPassword, | 169 | cryptPassword, |
132 | signJsonLDObject | 170 | signJsonLDObject, |
171 | |||
172 | encrypt, | ||
173 | decrypt | ||
133 | } | 174 | } |
134 | 175 | ||
135 | // --------------------------------------------------------------------------- | 176 | // --------------------------------------------------------------------------- |