Skip to content

Commit e3b0af0

Browse files
3nprob3nprob
authored andcommitted
Validate cert & key on set
1 parent 02e3982 commit e3b0af0

File tree

4 files changed

+48
-11
lines changed

4 files changed

+48
-11
lines changed

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"main": "app.js",
66
"bin": "./bin/matrix-appservice-irc",
77
"engines": {
8-
"node": ">=14"
8+
"node": ">=16"
99
},
1010
"scripts": {
1111
"prepare": "npm run build",
@@ -54,7 +54,7 @@
5454
"@types/extend": "^3.0.1",
5555
"@types/he": "^1.1.2",
5656
"@types/nedb": "^1.8.12",
57-
"@types/node": "^14",
57+
"@types/node": "^16",
5858
"@types/nopt": "^3.0.29",
5959
"@types/pg": "^8.6.4",
6060
"@types/sanitize-html": "^2.6.2",

src/bridge/AdminRoomHandler.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17+
import * as crypto from "crypto";
1718
import { BridgeRequest } from "../models/BridgeRequest";
1819
import { MatrixRoom, MatrixUser } from "matrix-appservice-bridge";
1920
import { IrcBridge } from "./IrcBridge";
@@ -601,6 +602,26 @@ export class AdminRoomHandler {
601602
);
602603
}
603604
else {
605+
try {
606+
const pk = crypto.createPrivateKey(key);
607+
const config = await this.ircBridge.getStore().getIrcClientConfig(userId, server.domain);
608+
if (config) {
609+
const cert = config.getSASLCert();
610+
if (cert) {
611+
const c = new crypto.X509Certificate(cert);
612+
if (!c.checkPrivateKey(pk)) {
613+
return new MatrixAction(
614+
"notice",
615+
"Private key does not match stored certificate. " +
616+
"To store a new pair, first call !removecert.\n"
617+
);
618+
}
619+
}
620+
}
621+
}
622+
catch (err) {
623+
throw new Error(`Invalid private key: ${err.message})`);
624+
}
604625
await this.ircBridge.getStore().storeKey(userId, domain, key);
605626
notice = new MatrixAction(
606627
"notice", `Successfully stored SASL key for ${domain}. Use !reconnect to reauthenticate.`
@@ -652,6 +673,22 @@ export class AdminRoomHandler {
652673
new MatrixUser(userId), server.domain
653674
);
654675
}
676+
try {
677+
const c = new crypto.X509Certificate(cert);
678+
const pk = config.getSASLKey();
679+
if (pk) {
680+
if (!c.checkPrivateKey(crypto.createPrivateKey(pk))) {
681+
return new MatrixAction(
682+
"notice",
683+
"Certificate does not match stored private key. " +
684+
"To store a new pair, first call !removekey.\n"
685+
);
686+
}
687+
}
688+
}
689+
catch (err) {
690+
throw new Error(`Invalid certificate: ${err.message})`);
691+
}
655692
config.setSASLCert(cert);
656693
await this.ircBridge.getStore().storeIrcClientConfig(config);
657694
notice = new MatrixAction(

src/bridge/RoomConfig.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export class RoomConfig {
5858
// We don't want to spend too long trying to fetch the state, so return null.
5959
return Promise.race([
6060
internalFunc(),
61-
new Promise<null>(res => setTimeout(res, STATE_TIMEOUT_MS)),
61+
new Promise<null>(res => setTimeout(res as unknown as ((args: void) => void), STATE_TIMEOUT_MS)),
6262
// We *never* want this function to throw, as it's critical for the bridging of messages.
6363
// Instead we return null for any errors.
6464
]).catch(ex => {

0 commit comments

Comments
 (0)