]>
Commit | Line | Data |
---|---|---|
65fcc311 C |
1 | import crypto = require('crypto') |
2 | import bcrypt = require('bcrypt') | |
3 | import fs = require('fs') | |
4 | import openssl = require('openssl-wrapper') | |
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 | |
bdfbd4f1 | 17 | function checkSignature (publicKey, data, hexSignature) { |
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 | ||
bdfbd4f1 | 38 | function sign (data) { |
65fcc311 | 39 | const sign = crypto.createSign(SIGNATURE_ALGORITHM) |
bdfbd4f1 C |
40 | |
41 | let dataString | |
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 | ||
26d7d31b C |
63 | function comparePassword (plainPassword, hashPassword, callback) { |
64 | bcrypt.compare(plainPassword, hashPassword, function (err, isPasswordMatch) { | |
65 | if (err) return callback(err) | |
66 | ||
67 | return callback(null, isPasswordMatch) | |
68 | }) | |
69 | } | |
70 | ||
9f10b292 | 71 | function createCertsIfNotExist (callback) { |
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 | |
26d7d31b | 85 | function cryptPassword (password, callback) { |
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 | ||
15103f11 | 95 | function getMyPrivateCert (callback) { |
65fcc311 | 96 | const certPath = join(CONFIG.STORAGE.CERT_DIR, PRIVATE_CERT_NAME) |
15103f11 C |
97 | fs.readFile(certPath, 'utf8', callback) |
98 | } | |
99 | ||
100 | function getMyPublicCert (callback) { | |
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 | |
9f10b292 | 119 | function certsExist (callback) { |
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 | ||
128 | function createCerts (callback) { | |
0dd079da C |
129 | certsExist(function (err, exist) { |
130 | if (err) return callback(err) | |
131 | ||
9f10b292 | 132 | if (exist === true) { |
f0f5567b | 133 | const string = 'Certs already exist.' |
9f10b292 C |
134 | logger.warning(string) |
135 | return callback(new Error(string)) | |
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 | } |