Skip to content

Commit

Permalink
Use OEAP SHA1 for now to support legacy strings.
Browse files Browse the repository at this point in the history
  • Loading branch information
Half-Shot committed Apr 17, 2024
1 parent 79bfffc commit b31f19c
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ atom_syndication = "0.12"
ruma = { version = "0.9", features = ["events", "html"] }
reqwest = "0.11"
rand = "0.8.5"
rsa = "0.9.6"
rsa = { version = "0.9.6", features = ["sha2"] }
base64ct = { version = "1.6.0", features = ["alloc"] }
sha1 = "0.10.6"
[build-dependencies]
napi-build = "2"
13 changes: 6 additions & 7 deletions src/tokens/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use napi::bindgen_prelude::Buffer;
use napi::Error;
use rsa::pkcs1::DecodeRsaPrivateKey;
use rsa::pkcs8::DecodePrivateKey;
use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
use rsa::{Oaep, RsaPrivateKey, RsaPublicKey};
use sha1::Sha1;

static MAX_TOKEN_PART_SIZE: usize = 128;

Expand Down Expand Up @@ -91,11 +92,12 @@ impl JsTokenEncryption {
}

fn decrypt_value(&self, value: String) -> Result<String, DecryptError> {
let padding = Oaep::new::<Sha1>();
let raw_value = Base64::decode_vec(&value).map_err(DecryptError::Base64)?;
let decrypted_value = self
.inner
.private_key
.decrypt(Pkcs1v15Encrypt, &raw_value)
.decrypt(padding, &raw_value)
.map_err(DecryptError::Decryption)?;
let utf8_value = String::from_utf8(decrypted_value).map_err(DecryptError::FromUtf8)?;
Ok(utf8_value)
Expand All @@ -106,11 +108,8 @@ impl JsTokenEncryption {
let mut rng = rand::thread_rng();
let mut parts: Vec<String> = Vec::new();
for part in input.into_bytes().chunks(MAX_TOKEN_PART_SIZE) {
match self
.inner
.public_key
.encrypt(&mut rng, Pkcs1v15Encrypt, part)
{
let padding = Oaep::new::<Sha1>();
match self.inner.public_key.encrypt(&mut rng, padding, part) {
Ok(encrypted) => {
let b64 = Base64::encode_string(encrypted.as_slice());
parts.push(b64);
Expand Down
19 changes: 18 additions & 1 deletion tests/tokens/tokenencryption.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TokenEncryption } from "../../src/libRs";
import { RSAKeyPairOptions, generateKeyPair } from "node:crypto";
import { RSAKeyPairOptions, generateKeyPair, publicEncrypt } from "node:crypto";
import { expect } from "chai";

describe("TokenEncryption", () => {
Expand All @@ -8,6 +8,18 @@ describe("TokenEncryption", () => {
async function createTokenEncryption() {
return new TokenEncryption(await keyPromise);
}

async function legacyEncryptFunction(token: string) {
const MAX_TOKEN_PART_SIZE = 128;
const tokenParts: string[] = [];
let tokenSource = token;
while (tokenSource && tokenSource.length > 0) {
const part = tokenSource.slice(0, MAX_TOKEN_PART_SIZE);
tokenSource = tokenSource.substring(MAX_TOKEN_PART_SIZE);
tokenParts.push(publicEncrypt(await keyPromise, Buffer.from(part)).toString("base64"));
}
return tokenParts;
}

before('generate RSA key', () => {
// Generate this once since it will take an age.
Expand Down Expand Up @@ -66,4 +78,9 @@ describe("TokenEncryption", () => {
const result = tokenEncryption.encrypt('hello world');
expect(result).to.have.lengthOf(1);
});
it('should be to decrypt a string from the old crypto implementation', async() => {
const legacyString = await legacyEncryptFunction('hello world');
const tokenEncryption = await createTokenEncryption();
expect(tokenEncryption.decrypt(legacyString)).to.equal('hello world');
});
});

0 comments on commit b31f19c

Please sign in to comment.