mirror of
https://github.com/matrix-org/matrix-hookshot.git
synced 2025-03-10 13:17:08 +00:00
Fix PKCS1 handling (#929)
* Support pkcs1 format keys. * Test pkcs1 support. * changelog * rust formatting
This commit is contained in:
parent
4839340c86
commit
ff200114a6
1
changelog.d/929.bugfix
Normal file
1
changelog.d/929.bugfix
Normal file
@ -0,0 +1 @@
|
||||
Track which key was used to encrypt secrets in storage, and encrypt/decrypt secrets in Rust.
|
@ -3,6 +3,7 @@ use std::string::FromUtf8Error;
|
||||
use base64ct::{Base64, Encoding};
|
||||
use napi::bindgen_prelude::Buffer;
|
||||
use napi::Error;
|
||||
use rsa::pkcs1::DecodeRsaPrivateKey;
|
||||
use rsa::pkcs8::DecodePrivateKey;
|
||||
use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
|
||||
|
||||
@ -17,7 +18,9 @@ struct TokenEncryption {
|
||||
#[allow(dead_code)]
|
||||
enum TokenEncryptionError {
|
||||
FromUtf8(FromUtf8Error),
|
||||
PrivateKey(rsa::pkcs8::Error),
|
||||
UnknownFormat,
|
||||
PrivateKey8(rsa::pkcs8::Error),
|
||||
PrivateKey1(rsa::pkcs1::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -31,8 +34,16 @@ enum DecryptError {
|
||||
impl TokenEncryption {
|
||||
pub fn new(private_key_data: Vec<u8>) -> Result<Self, TokenEncryptionError> {
|
||||
let data = String::from_utf8(private_key_data).map_err(TokenEncryptionError::FromUtf8)?;
|
||||
let private_key = RsaPrivateKey::from_pkcs8_pem(data.as_str())
|
||||
.map_err(TokenEncryptionError::PrivateKey)?;
|
||||
let private_key: RsaPrivateKey;
|
||||
if data.starts_with("-----BEGIN PRIVATE KEY-----") {
|
||||
private_key = RsaPrivateKey::from_pkcs8_pem(data.as_str())
|
||||
.map_err(TokenEncryptionError::PrivateKey8)?;
|
||||
} else if data.starts_with("-----BEGIN RSA PRIVATE KEY-----") {
|
||||
private_key = RsaPrivateKey::from_pkcs1_pem(data.as_str())
|
||||
.map_err(TokenEncryptionError::PrivateKey1)?;
|
||||
} else {
|
||||
return Err(TokenEncryptionError::UnknownFormat);
|
||||
}
|
||||
let public_key = private_key.to_public_key();
|
||||
Ok(TokenEncryption {
|
||||
private_key,
|
||||
|
@ -4,6 +4,7 @@ import { expect } from "chai";
|
||||
|
||||
describe("TokenEncryption", () => {
|
||||
let keyPromise: Promise<Buffer>;
|
||||
let keyPromisePKCS1: Promise<Buffer>;
|
||||
async function createTokenEncryption() {
|
||||
return new TokenEncryption(await keyPromise);
|
||||
}
|
||||
@ -24,6 +25,21 @@ describe("TokenEncryption", () => {
|
||||
} satisfies RSAKeyPairOptions<"pem", "pem">, (err, _, privateKey) => {
|
||||
if (err) { reject(err) } else { resolve(Buffer.from(privateKey)) }
|
||||
}));
|
||||
keyPromisePKCS1 = new Promise<Buffer>((resolve, reject) => generateKeyPair("rsa", {
|
||||
// Deliberately shorter length to speed up test
|
||||
modulusLength: 2048,
|
||||
privateKeyEncoding: {
|
||||
type: "pkcs1",
|
||||
format: "pem",
|
||||
},
|
||||
publicKeyEncoding: {
|
||||
format: "pem",
|
||||
type: "pkcs1",
|
||||
}
|
||||
} satisfies RSAKeyPairOptions<"pem", "pem">, (err, _, privateKey) => {
|
||||
if (err) { reject(err) } else { resolve(Buffer.from(privateKey)) }
|
||||
}));
|
||||
|
||||
}, );
|
||||
it('should be able to encrypt a string into a single part', async() => {
|
||||
const tokenEncryption = await createTokenEncryption();
|
||||
@ -45,4 +61,9 @@ describe("TokenEncryption", () => {
|
||||
const result = tokenEncryption.decrypt(value);
|
||||
expect(result).to.equal(plaintext);
|
||||
});
|
||||
it('should support pkcs1 format keys', async() => {
|
||||
const tokenEncryption = new TokenEncryption(await keyPromisePKCS1);
|
||||
const result = tokenEncryption.encrypt('hello world');
|
||||
expect(result).to.have.lengthOf(1);
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user