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