aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers/peertube-crypto.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/helpers/peertube-crypto.ts')
-rw-r--r--server/helpers/peertube-crypto.ts158
1 files changed, 46 insertions, 112 deletions
diff --git a/server/helpers/peertube-crypto.ts b/server/helpers/peertube-crypto.ts
index 10a226af4..6d50e446f 100644
--- a/server/helpers/peertube-crypto.ts
+++ b/server/helpers/peertube-crypto.ts
@@ -1,77 +1,68 @@
1import * as crypto from 'crypto' 1import * as jsig from 'jsonld-signatures'
2import { join } from 'path'
3 2
4import { 3import {
5 SIGNATURE_ALGORITHM, 4 PRIVATE_RSA_KEY_SIZE,
6 SIGNATURE_ENCODING, 5 BCRYPT_SALT_SIZE
7 PRIVATE_CERT_NAME,
8 CONFIG,
9 BCRYPT_SALT_SIZE,
10 PUBLIC_CERT_NAME
11} from '../initializers' 6} from '../initializers'
12import { 7import {
13 readFilePromise,
14 bcryptComparePromise, 8 bcryptComparePromise,
15 bcryptGenSaltPromise, 9 bcryptGenSaltPromise,
16 bcryptHashPromise, 10 bcryptHashPromise,
17 accessPromise, 11 createPrivateKey,
18 opensslExecPromise 12 getPublicKey,
13 jsonldSignPromise,
14 jsonldVerifyPromise
19} from './core-utils' 15} from './core-utils'
20import { logger } from './logger' 16import { logger } from './logger'
17import { AccountInstance } from '../models/account/account-interface'
21 18
22function checkSignature (publicKey: string, data: string, hexSignature: string) { 19async function createPrivateAndPublicKeys () {
23 const verify = crypto.createVerify(SIGNATURE_ALGORITHM) 20 logger.info('Generating a RSA key...')
24
25 let dataString
26 if (typeof data === 'string') {
27 dataString = data
28 } else {
29 try {
30 dataString = JSON.stringify(data)
31 } catch (err) {
32 logger.error('Cannot check signature.', err)
33 return false
34 }
35 }
36 21
37 verify.update(dataString, 'utf8') 22 const { key } = await createPrivateKey(PRIVATE_RSA_KEY_SIZE)
23 const { publicKey } = await getPublicKey(key)
38 24
39 const isValid = verify.verify(publicKey, hexSignature, SIGNATURE_ENCODING) 25 return { privateKey: key, publicKey }
40 return isValid
41} 26}
42 27
43async function sign (data: string | Object) { 28function isSignatureVerified (fromAccount: AccountInstance, signedDocument: object) {
44 const sign = crypto.createSign(SIGNATURE_ALGORITHM) 29 const publicKeyObject = {
45 30 '@context': jsig.SECURITY_CONTEXT_URL,
46 let dataString: string 31 '@id': fromAccount.url,
47 if (typeof data === 'string') { 32 '@type': 'CryptographicKey',
48 dataString = data 33 owner: fromAccount.url,
49 } else { 34 publicKeyPem: fromAccount.publicKey
50 try {
51 dataString = JSON.stringify(data)
52 } catch (err) {
53 logger.error('Cannot sign data.', err)
54 return ''
55 }
56 } 35 }
57 36
58 sign.update(dataString, 'utf8') 37 const publicKeyOwnerObject = {
38 '@context': jsig.SECURITY_CONTEXT_URL,
39 '@id': fromAccount.url,
40 publicKey: [ publicKeyObject ]
41 }
59 42
60 const myKey = await getMyPrivateCert() 43 const options = {
61 return sign.sign(myKey, SIGNATURE_ENCODING) 44 publicKey: publicKeyObject,
62} 45 publicKeyOwner: publicKeyOwnerObject
46 }
63 47
64function comparePassword (plainPassword: string, hashPassword: string) { 48 return jsonldVerifyPromise(signedDocument, options)
65 return bcryptComparePromise(plainPassword, hashPassword) 49 .catch(err => {
50 logger.error('Cannot check signature.', err)
51 return false
52 })
66} 53}
67 54
68async function createCertsIfNotExist () { 55function signObject (byAccount: AccountInstance, data: any) {
69 const exist = await certsExist() 56 const options = {
70 if (exist === true) { 57 privateKeyPem: byAccount.privateKey,
71 return 58 creator: byAccount.url
72 } 59 }
73 60
74 return createCerts() 61 return jsonldSignPromise(data, options)
62}
63
64function comparePassword (plainPassword: string, hashPassword: string) {
65 return bcryptComparePromise(plainPassword, hashPassword)
75} 66}
76 67
77async function cryptPassword (password: string) { 68async function cryptPassword (password: string) {
@@ -80,69 +71,12 @@ async function cryptPassword (password: string) {
80 return bcryptHashPromise(password, salt) 71 return bcryptHashPromise(password, salt)
81} 72}
82 73
83function getMyPrivateCert () {
84 const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
85 return readFilePromise(certPath, 'utf8')
86}
87
88function getMyPublicCert () {
89 const certPath = join(CONFIG.STORAGE.CERT_DIR, PUBLIC_CERT_NAME)
90 return readFilePromise(certPath, 'utf8')
91}
92
93// --------------------------------------------------------------------------- 74// ---------------------------------------------------------------------------
94 75
95export { 76export {
96 checkSignature, 77 isSignatureVerified,
97 comparePassword, 78 comparePassword,
98 createCertsIfNotExist, 79 createPrivateAndPublicKeys,
99 cryptPassword, 80 cryptPassword,
100 getMyPrivateCert, 81 signObject
101 getMyPublicCert,
102 sign
103}
104
105// ---------------------------------------------------------------------------
106
107async function certsExist () {
108 const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
109
110 // If there is an error the certificates do not exist
111 try {
112 await accessPromise(certPath)
113
114 return true
115 } catch {
116 return false
117 }
118}
119
120async function createCerts () {
121 const exist = await certsExist()
122 if (exist === true) {
123 const errorMessage = 'Certs already exist.'
124 logger.warning(errorMessage)
125 throw new Error(errorMessage)
126 }
127
128 logger.info('Generating a RSA key...')
129
130 const privateCertPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME)
131 const genRsaOptions = {
132 'out': privateCertPath,
133 '2048': false
134 }
135
136 await opensslExecPromise('genrsa', genRsaOptions)
137 logger.info('RSA key generated.')
138 logger.info('Managing public key...')
139
140 const publicCertPath = join(CONFIG.STORAGE.CERT_DIR, 'peertube.pub')
141 const rsaOptions = {
142 'in': privateCertPath,
143 'pubout': true,
144 'out': publicCertPath
145 }
146
147 await opensslExecPromise('rsa', rsaOptions)
148} 82}