]>
Commit | Line | Data |
---|---|---|
4d4e5cd4 | 1 | import * as crypto from 'crypto' |
709756b8 | 2 | import * as Promise from 'bluebird' |
65fcc311 C |
3 | import { join } from 'path' |
4 | ||
5 | import { | |
6 | SIGNATURE_ALGORITHM, | |
7 | SIGNATURE_ENCODING, | |
8 | PRIVATE_CERT_NAME, | |
9 | CONFIG, | |
10 | BCRYPT_SALT_SIZE, | |
11 | PUBLIC_CERT_NAME | |
12 | } from '../initializers' | |
6fcd19ba C |
13 | import { |
14 | readFilePromise, | |
15 | bcryptComparePromise, | |
16 | bcryptGenSaltPromise, | |
17 | bcryptHashPromise, | |
18 | accessPromise, | |
19 | opensslExecPromise | |
20 | } from './core-utils' | |
65fcc311 | 21 | import { logger } from './logger' |
9f10b292 | 22 | |
69818c93 | 23 | function checkSignature (publicKey: string, data: string, hexSignature: string) { |
65fcc311 | 24 | const verify = crypto.createVerify(SIGNATURE_ALGORITHM) |
bdfbd4f1 C |
25 | |
26 | let dataString | |
27 | if (typeof data === 'string') { | |
28 | dataString = data | |
29 | } else { | |
30 | try { | |
31 | dataString = JSON.stringify(data) | |
32 | } catch (err) { | |
ad0997ad | 33 | logger.error('Cannot check signature.', err) |
bdfbd4f1 C |
34 | return false |
35 | } | |
36 | } | |
37 | ||
38 | verify.update(dataString, 'utf8') | |
39 | ||
65fcc311 | 40 | const isValid = verify.verify(publicKey, hexSignature, SIGNATURE_ENCODING) |
bc503c2a | 41 | return isValid |
9f10b292 C |
42 | } |
43 | ||
69818c93 | 44 | function sign (data: string|Object) { |
65fcc311 | 45 | const sign = crypto.createSign(SIGNATURE_ALGORITHM) |
bdfbd4f1 | 46 | |
69818c93 | 47 | let dataString: string |
bdfbd4f1 C |
48 | if (typeof data === 'string') { |
49 | dataString = data | |
50 | } else { | |
51 | try { | |
52 | dataString = JSON.stringify(data) | |
53 | } catch (err) { | |
ad0997ad | 54 | logger.error('Cannot sign data.', err) |
709756b8 | 55 | return Promise.resolve('') |
bdfbd4f1 C |
56 | } |
57 | } | |
58 | ||
59 | sign.update(dataString, 'utf8') | |
60 | ||
709756b8 C |
61 | return getMyPrivateCert().then(myKey => { |
62 | return sign.sign(myKey, SIGNATURE_ENCODING) | |
63 | }) | |
bdfbd4f1 C |
64 | } |
65 | ||
6fcd19ba C |
66 | function comparePassword (plainPassword: string, hashPassword: string) { |
67 | return bcryptComparePromise(plainPassword, hashPassword) | |
26d7d31b C |
68 | } |
69 | ||
6fcd19ba C |
70 | function createCertsIfNotExist () { |
71 | return certsExist().then(exist => { | |
9f10b292 | 72 | if (exist === true) { |
6fcd19ba | 73 | return undefined |
9f10b292 C |
74 | } |
75 | ||
6fcd19ba | 76 | return createCerts() |
9f10b292 C |
77 | }) |
78 | } | |
dac0a531 | 79 | |
6fcd19ba C |
80 | function cryptPassword (password: string) { |
81 | return bcryptGenSaltPromise(BCRYPT_SALT_SIZE).then(salt => bcryptHashPromise(password, salt)) | |
26d7d31b C |
82 | } |
83 | ||
6fcd19ba | 84 | function getMyPrivateCert () { |
65fcc311 | 85 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME) |
6fcd19ba | 86 | return readFilePromise(certPath, 'utf8') |
15103f11 C |
87 | } |
88 | ||
6fcd19ba | 89 | function getMyPublicCert () { |
65fcc311 | 90 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PUBLIC_CERT_NAME) |
6fcd19ba | 91 | return readFilePromise(certPath, 'utf8') |
15103f11 C |
92 | } |
93 | ||
9f10b292 | 94 | // --------------------------------------------------------------------------- |
dac0a531 | 95 | |
65fcc311 C |
96 | export { |
97 | checkSignature, | |
98 | comparePassword, | |
99 | createCertsIfNotExist, | |
100 | cryptPassword, | |
101 | getMyPrivateCert, | |
102 | getMyPublicCert, | |
103 | sign | |
104 | } | |
dac0a531 | 105 | |
9f10b292 | 106 | // --------------------------------------------------------------------------- |
dac0a531 | 107 | |
6fcd19ba | 108 | function certsExist () { |
65fcc311 | 109 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME) |
9f10b292 | 110 | |
6fcd19ba C |
111 | // If there is an error the certificates do not exist |
112 | return accessPromise(certPath) | |
113 | .then(() => true) | |
114 | .catch(() => false) | |
115 | } | |
0dd079da | 116 | |
6fcd19ba C |
117 | function createCerts () { |
118 | return certsExist().then(exist => { | |
9f10b292 | 119 | if (exist === true) { |
69818c93 C |
120 | const errorMessage = 'Certs already exist.' |
121 | logger.warning(errorMessage) | |
6fcd19ba | 122 | throw new Error(errorMessage) |
9f10b292 C |
123 | } |
124 | ||
125 | logger.info('Generating a RSA key...') | |
e861452f | 126 | |
65fcc311 | 127 | const privateCertPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME) |
15103f11 C |
128 | const genRsaOptions = { |
129 | 'out': privateCertPath, | |
e861452f C |
130 | '2048': false |
131 | } | |
6fcd19ba C |
132 | return opensslExecPromise('genrsa', genRsaOptions) |
133 | .then(() => { | |
134 | logger.info('RSA key generated.') | |
135 | logger.info('Managing public key...') | |
136 | ||
137 | const publicCertPath = join(CONFIG.STORAGE.CERT_DIR, 'peertube.pub') | |
138 | const rsaOptions = { | |
139 | 'in': privateCertPath, | |
140 | 'pubout': true, | |
141 | 'out': publicCertPath | |
dac0a531 | 142 | } |
6fcd19ba C |
143 | return opensslExecPromise('rsa', rsaOptions) |
144 | .then(() => logger.info('Public key managed.')) | |
145 | .catch(err => { | |
146 | logger.error('Cannot create public key on this pod.') | |
147 | throw err | |
148 | }) | |
149 | }) | |
150 | .catch(err => { | |
151 | logger.error('Cannot create private key on this pod.') | |
152 | throw err | |
9f10b292 | 153 | }) |
9f10b292 C |
154 | }) |
155 | } |