Skip to content

Commit 74a5d91

Browse files
authored
fix: buffer conversion bug (#518)
1 parent fd203f8 commit 74a5d91

File tree

8 files changed

+211
-135
lines changed

8 files changed

+211
-135
lines changed

.github/workflows/update-lockfiles.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
name: 'Update Lockfiles (bun.lockb + Podfile.lock)'
22

33
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- ".github/workflows/update-lockfiles.yml"
49
pull_request:
510
paths:
11+
- ".github/workflows/update-lockfiles.yml"
612
- "package.json"
713
- "example/package.json"
814

@@ -12,7 +18,7 @@ permissions:
1218
jobs:
1319
update-lockfiles:
1420
name: "Update lockfiles (bun.lockb + Podfile.lock)"
15-
# if: github.actor == 'dependabot[bot]'
21+
if: github.actor == 'dependabot[bot]'
1622
runs-on: macOS-latest
1723
steps:
1824
- name: Checkout Code

.github/workflows/validate-js.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ jobs:
8888
bun install
8989
9090
- name: Run ESLint/Prettier (rnqc)
91-
run: bun lint-fix && bun format-fix
91+
run: bun lint:fix && bun format:fix
9292

9393
- name: Run ESLint/Prettier (example)
9494
run:
95-
cd example && bun lint-fix && bun format-fix
95+
cd example && bun lint:fix && bun format:fix
9696

9797
- name: Verify no files have changed after auto-fix
9898
run: git diff --exit-code HEAD -- . ':(exclude)bun.lockb'

example/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
"tsc": "tsc --noEmit",
1111
"typescript": "tsc --noEmit",
1212
"lint": "eslint \"**/*.{js,ts,tsx}\"",
13-
"lint-fix": "eslint \"**/*.{js,ts,tsx}\" --fix",
13+
"lint:fix": "eslint \"**/*.{js,ts,tsx}\" --fix",
1414
"lint-ci": "bun lint -f ../node_modules/@firmnav/eslint-github-actions-formatter/dist/formatter.js",
1515
"format": "prettier --check \"**/*.{js,ts,tsx}\"",
16-
"format-fix": "prettier --write \"**/*.{js,ts,tsx}\"",
16+
"format:fix": "prettier --write \"**/*.{js,ts,tsx}\"",
1717
"start": "react-native start",
1818
"test": "jest",
1919
"pods": "bundle install && bundle exec pod install --project-directory=ios/",

example/src/hooks/useTestList.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ import '../testing/tests/HmacTests/HmacTests';
99
import '../testing/tests/HashTests/HashTests';
1010
import '../testing/tests/CipherTests/CipherDecipher';
1111
import '../testing/tests/CipherTests/CipherivDecipheriv';
12-
import '../testing/tests/CipherTests/test398';
1312
import '../testing/tests/CipherTests/PublicCipherTests';
1413
import '../testing/tests/CipherTests/generateKey';
1514
import '../testing/tests/CipherTests/GenerateKeyPairTests';
1615
import '../testing/tests/ConstantsTests/ConstantsTests';
1716
import '../testing/tests/SignTests/SignTests';
18-
import '../testing/tests/SmokeTests/bundlerTests';
1917
import '../testing/tests/webcryptoTests/deriveBits';
2018
import '../testing/tests/webcryptoTests/digest';
2119
import '../testing/tests/webcryptoTests/generateKey';
2220
import '../testing/tests/webcryptoTests/encrypt_decrypt';
2321
import '../testing/tests/webcryptoTests/import_export';
2422
import '../testing/tests/webcryptoTests/sign_verify';
23+
import '../testing/tests/SmokeTests/bundlerTests';
24+
import '../testing/tests/issues/specific_issues';
2525

2626
export const useTestList = (): [
2727
Suites,

example/src/testing/tests/CipherTests/test398.ts

-104
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import type { BinaryLikeNode } from '../../../../../src/Utils';
2+
import { Buffer as CraftzdogBuffer } from '@craftzdog/react-native-buffer';
3+
import { Buffer as FerossBuffer } from 'buffer';
4+
import crypto from 'react-native-quick-crypto';
5+
import { describe, it } from '../../MochaRNAdapter';
6+
import { expect } from 'chai';
7+
8+
// -----------------------------------------------------------------------------
9+
// tests
10+
11+
describe('specific issues', () => {
12+
it('issue 398', () => {
13+
const publicKeySpkiBase64 =
14+
'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENlFpbMBNfCY6Lhj9A/clefyxJVIXGJ0y6CcZ/cbbyyebvN6T0aNPvpQyFdUwRtYvFHlYbqIZOM8AoqdPcnSMIA==';
15+
16+
const publicKey = getPublicKeyInPEMFormat(publicKeySpkiBase64);
17+
// console.log('\n' + publicKey);
18+
const encrypted = encrypt({
19+
payload: JSON.stringify({ a: 1 }),
20+
publicKey,
21+
});
22+
// console.log({ encrypted });
23+
const { response: decrypted } = decrypt({
24+
response: encrypted,
25+
secretKey: encrypted.secretKey,
26+
});
27+
expect(decrypted).to.equal({ a: 1 });
28+
});
29+
30+
const largeKey = crypto.randomBytes(64);
31+
it('issue 505 - craftzdog buffer', () => {
32+
// an instance of CraftzdogBuffer
33+
testBufferConversion('test', largeKey);
34+
});
35+
it('issue 505 - feross buffer', () => {
36+
// not an instance of CraftzdogBuffer
37+
const largeKeyFeross = FerossBuffer.from(
38+
largeKey.toString('base64'),
39+
'base64',
40+
);
41+
testBufferConversion('test', largeKeyFeross);
42+
});
43+
});
44+
45+
// -----------------------------------------------------------------------------
46+
// #398
47+
type EncryptRequest = {
48+
payload: string;
49+
publicKey: ArrayBuffer;
50+
};
51+
type EncryptResponse = {
52+
KEY: string;
53+
IV: string;
54+
PAYLOAD: string;
55+
secretKey: BinaryLikeNode;
56+
};
57+
58+
const algo = 'aes-128-gcm';
59+
60+
const encrypt = ({ payload, publicKey }: EncryptRequest): EncryptResponse => {
61+
const secretKey = crypto.randomBytes(16);
62+
const iv = crypto.randomBytes(16);
63+
64+
const cipher = crypto.createCipheriv(algo, secretKey, iv);
65+
66+
const encryptedPayload = FerossBuffer.concat([
67+
cipher.update(payload, 'utf8'),
68+
cipher.final(),
69+
cipher.getAuthTag(),
70+
]).toString('base64');
71+
72+
const encryptedSessionKey = crypto.publicEncrypt(
73+
{
74+
key: publicKey,
75+
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
76+
},
77+
secretKey,
78+
);
79+
80+
return {
81+
KEY: encryptedSessionKey.toString('base64'),
82+
IV: iv.toString('base64'),
83+
PAYLOAD: encryptedPayload,
84+
secretKey,
85+
};
86+
};
87+
88+
const decrypt = ({
89+
response,
90+
secretKey,
91+
}: {
92+
response: EncryptResponse;
93+
secretKey: BinaryLikeNode;
94+
}) => {
95+
const { IV, PAYLOAD } = response;
96+
97+
const decipher = crypto.createDecipheriv(
98+
algo,
99+
secretKey,
100+
FerossBuffer.from(IV, 'base64'),
101+
);
102+
103+
const encryptedPayload = FerossBuffer.from(PAYLOAD, 'base64');
104+
let decrypted = decipher.update(
105+
FerossBuffer.from(
106+
encryptedPayload.subarray(0, encryptedPayload.length - 16),
107+
),
108+
);
109+
decrypted = FerossBuffer.concat([decrypted, decipher.final()]);
110+
111+
return JSON.parse(decrypted.toString('utf8'));
112+
};
113+
114+
const getPublicKeyInPEMFormat = (key: string): ArrayBuffer => {
115+
return crypto
116+
.createPublicKey({
117+
key: FerossBuffer.from(key, 'base64'),
118+
format: 'der',
119+
type: 'spki',
120+
})
121+
.export({
122+
type: 'spki',
123+
format: 'pem',
124+
});
125+
};
126+
127+
// -----------------------------------------------------------------------------
128+
// #505
129+
const testBufferConversion = (
130+
clearText: string,
131+
largeKey: CraftzdogBuffer | FerossBuffer,
132+
) => {
133+
const key = largeKey.subarray(32);
134+
const iv = crypto.randomBytes(16);
135+
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
136+
const enc = CraftzdogBuffer.concat([
137+
cipher.update(
138+
CraftzdogBuffer.from(clearText),
139+
) as unknown as CraftzdogBuffer,
140+
cipher.final() as unknown as CraftzdogBuffer,
141+
]);
142+
const encB64 = enc.toString('base64');
143+
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
144+
const dec = CraftzdogBuffer.concat([
145+
decipher.update(
146+
CraftzdogBuffer.from(encB64, 'base64'),
147+
) as unknown as CraftzdogBuffer,
148+
decipher.final() as unknown as CraftzdogBuffer,
149+
]);
150+
expect(dec.toString()).to.equal(clearText);
151+
};

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
"tsc": "tsc --noEmit",
3030
"typescript": "tsc --noEmit",
3131
"lint": "eslint \"**/*.{js,ts,tsx}\"",
32-
"lint-fix": "eslint \"**/*.{js,ts,tsx}\" --fix",
32+
"lint:fix": "eslint \"**/*.{js,ts,tsx}\" --fix",
3333
"format": "prettier --check \"**/*.{js,ts,tsx}\"",
34-
"format-fix": "prettier --write \"**/*.{js,ts,tsx}\"",
34+
"format:fix": "prettier --write \"**/*.{js,ts,tsx}\"",
3535
"prepare": "bob build",
3636
"release": "release-it",
3737
"example": "cd example && bun start",

0 commit comments

Comments
 (0)