]>
Commit | Line | Data |
---|---|---|
1 | import * as crypto from 'crypto' | |
2 | import { join } from 'path' | |
3 | ||
4 | import { | |
5 | SIGNATURE_ALGORITHM, | |
6 | SIGNATURE_ENCODING, | |
7 | PRIVATE_CERT_NAME, | |
8 | CONFIG, | |
9 | BCRYPT_SALT_SIZE, | |
10 | PUBLIC_CERT_NAME | |
11 | } from '../initializers' | |
12 | import { | |
13 | readFilePromise, | |
14 | bcryptComparePromise, | |
15 | bcryptGenSaltPromise, | |
16 | bcryptHashPromise, | |
17 | accessPromise, | |
18 | opensslExecPromise | |
19 | } from './core-utils' | |
20 | import { logger } from './logger' | |
21 | ||
22 | function checkSignature (publicKey: string, data: string, hexSignature: string) { | |
23 | const verify = crypto.createVerify(SIGNATURE_ALGORITHM) | |
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 | ||
37 | verify.update(dataString, 'utf8') | |
38 | ||
39 | const isValid = verify.verify(publicKey, hexSignature, SIGNATURE_ENCODING) | |
40 | return isValid | |
41 | } | |
42 | ||
43 | async function sign (data: string | Object) { | |
44 | const sign = crypto.createSign(SIGNATURE_ALGORITHM) | |
45 | ||
46 | let dataString: string | |
47 | if (typeof data === 'string') { | |
48 | dataString = data | |
49 | } else { | |
50 | try { | |
51 | dataString = JSON.stringify(data) | |
52 | } catch (err) { | |
53 | logger.error('Cannot sign data.', err) | |
54 | return '' | |
55 | } | |
56 | } | |
57 | ||
58 | sign.update(dataString, 'utf8') | |
59 | ||
60 | const myKey = await getMyPrivateCert() | |
61 | return sign.sign(myKey, SIGNATURE_ENCODING) | |
62 | } | |
63 | ||
64 | function comparePassword (plainPassword: string, hashPassword: string) { | |
65 | return bcryptComparePromise(plainPassword, hashPassword) | |
66 | } | |
67 | ||
68 | async function createCertsIfNotExist () { | |
69 | const exist = await certsExist() | |
70 | if (exist === true) { | |
71 | return | |
72 | } | |
73 | ||
74 | return createCerts() | |
75 | } | |
76 | ||
77 | async function cryptPassword (password: string) { | |
78 | const salt = await bcryptGenSaltPromise(BCRYPT_SALT_SIZE) | |
79 | ||
80 | return bcryptHashPromise(password, salt) | |
81 | } | |
82 | ||
83 | function getMyPrivateCert () { | |
84 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME) | |
85 | return readFilePromise(certPath, 'utf8') | |
86 | } | |
87 | ||
88 | function getMyPublicCert () { | |
89 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PUBLIC_CERT_NAME) | |
90 | return readFilePromise(certPath, 'utf8') | |
91 | } | |
92 | ||
93 | // --------------------------------------------------------------------------- | |
94 | ||
95 | export { | |
96 | checkSignature, | |
97 | comparePassword, | |
98 | createCertsIfNotExist, | |
99 | cryptPassword, | |
100 | getMyPrivateCert, | |
101 | getMyPublicCert, | |
102 | sign | |
103 | } | |
104 | ||
105 | // --------------------------------------------------------------------------- | |
106 | ||
107 | async 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 | ||
120 | async 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 | } |