Skip to content

Commit fd1e4b7

Browse files
committed
cipher init works, js internals closer to recent node updates
1 parent 2feb4f8 commit fd1e4b7

4 files changed

Lines changed: 65 additions & 25 deletions

File tree

example/src/tests/cipher/cipher_tests.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
Cipher,
32
getCiphers,
43
createCipheriv,
54
randomFillSync,
@@ -12,8 +11,9 @@ const key = 'secret';
1211
const iv = randomFillSync(new Uint8Array(16));
1312

1413
test(SUITE, 'cipher - valid algorithm', async () => {
15-
const cipher = createCipheriv('aes-128-cbc', key, iv, {});
16-
expect(cipher).to.be.instanceOf(Cipher);
14+
expect(() => {
15+
createCipheriv('aes-128-cbc', key, iv, {});
16+
}).to.not.throw();
1717
});
1818

1919
test(SUITE, 'cipher - invalid algorithm', async () => {

packages/react-native-quick-crypto/cpp/cipher/HybridCipher.cpp

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77

88
namespace margelo::nitro::crypto {
99

10+
HybridCipher::~HybridCipher() {
11+
if (this->ctx) {
12+
EVP_CIPHER_CTX_free(this->ctx);
13+
}
14+
if (this->cipher) {
15+
EVP_CIPHER_free(this->cipher);
16+
}
17+
}
18+
1019
std::shared_ptr<ArrayBuffer>
1120
HybridCipher::update(
1221
const std::shared_ptr<ArrayBuffer>& data
@@ -65,12 +74,39 @@ HybridCipher::init() {
6574
}
6675
auto args = this->args.value();
6776

68-
// check if cipherType is valid
69-
const EVP_CIPHER *const cipher = EVP_get_cipherbyname(args.cipherType.c_str());
77+
// fetch cipher
78+
this->cipher = EVP_CIPHER_fetch(
79+
nullptr,
80+
args.cipherType.c_str(),
81+
nullptr
82+
);
7083
if (cipher == nullptr) {
7184
throw std::runtime_error("Invalid Cipher Algorithm: " + args.cipherType);
7285
}
7386

87+
// Create cipher context
88+
this->ctx = EVP_CIPHER_CTX_new();
89+
if (!this->ctx) {
90+
throw std::runtime_error("Failed to create cipher context");
91+
}
92+
93+
// Initialize cipher operation
94+
if (
95+
EVP_CipherInit_ex2(
96+
this->ctx,
97+
this->cipher,
98+
this->args->cipherKey->data(),
99+
this->args->iv->data(),
100+
this->args->isCipher ? 1 : 0,
101+
nullptr
102+
) != 1
103+
) {
104+
EVP_CIPHER_CTX_free(this->ctx);
105+
this->ctx = nullptr;
106+
throw std::runtime_error("Failed to initialize encryption");
107+
}
108+
}
109+
74110
void collect_ciphers(EVP_CIPHER *cipher, void *arg) {
75111
auto ciphers = static_cast<std::vector<std::string>*>(arg);
76112
const char* name = EVP_CIPHER_get0_name(cipher);

packages/react-native-quick-crypto/cpp/cipher/HybridCipher.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ using namespace facebook;
1414
class HybridCipher : public HybridCipherSpec {
1515
public:
1616
HybridCipher() : HybridObject(TAG) {}
17+
~HybridCipher();
1718

1819
public:
1920
// Methods
@@ -62,6 +63,8 @@ class HybridCipher : public HybridCipherSpec {
6263
private:
6364
// Properties
6465
std::optional<CipherArgs> args = std::nullopt;
66+
EVP_CIPHER_CTX *ctx = nullptr;
67+
EVP_CIPHER *cipher = nullptr;
6568
};
6669

6770
} // namespace margelo::nitro::crypto

packages/react-native-quick-crypto/src/cipher.ts

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import {
2929
} from './utils/cipher';
3030

3131
class CipherUtils {
32-
private static native = NitroModules.createHybridObject<NativeCipher>('Cipher');
32+
private static native =
33+
NitroModules.createHybridObject<NativeCipher>('Cipher');
3334
public static getSupportedCiphers(): string[] {
3435
return this.native.getSupportedCiphers();
3536
}
@@ -40,23 +41,23 @@ export function getCiphers(): string[] {
4041
}
4142

4243
interface CipherArgs {
44+
isCipher: boolean;
4345
cipherType: string;
4446
cipherKey: BinaryLikeNode;
45-
isCipher: boolean;
46-
options: Record<string, TransformOptions>;
4747
iv: BinaryLike;
48-
};
48+
options: Record<string, TransformOptions>;
49+
}
4950

5051
class CipherCommon extends Stream.Transform {
5152
private native: NativeCipher;
5253
private decoder: StringDecoder | undefined;
5354

5455
constructor({
56+
isCipher,
5557
cipherType,
5658
cipherKey,
57-
isCipher,
58-
options = {},
5959
iv,
60+
options = {},
6061
}: CipherArgs) {
6162
super(options);
6263
this.native = NitroModules.createHybridObject<NativeCipher>('Cipher');
@@ -166,35 +167,35 @@ class CipherCommon extends Stream.Transform {
166167
}
167168
}
168169

169-
export class Cipher extends CipherCommon {
170+
class Cipheriv extends CipherCommon {
170171
constructor(
171172
cipherType: string,
172173
cipherKey: BinaryLikeNode,
173-
options: Record<string, TransformOptions> = {},
174174
iv: BinaryLike,
175+
options: Record<string, TransformOptions> = {},
175176
) {
176177
super({
178+
isCipher: true,
177179
cipherType,
178180
cipherKey: binaryLikeToArrayBuffer(cipherKey),
179181
iv: binaryLikeToArrayBuffer(iv),
180-
isCipher: true,
181182
options,
182183
});
183184
}
184185
}
185186

186-
export class Decipher extends CipherCommon {
187+
class Decipheriv extends CipherCommon {
187188
constructor(
188189
cipherType: string,
189190
cipherKey: BinaryLikeNode,
190-
options: Record<string, TransformOptions> = {},
191191
iv: BinaryLike,
192+
options: Record<string, TransformOptions> = {},
192193
) {
193194
super({
195+
isCipher: false,
194196
cipherType,
195197
cipherKey: binaryLikeToArrayBuffer(cipherKey),
196198
iv: binaryLikeToArrayBuffer(iv),
197-
isCipher: false,
198199
options,
199200
});
200201
}
@@ -223,7 +224,7 @@ export function createDecipheriv(
223224
key: BinaryLikeNode,
224225
iv: BinaryLike,
225226
options?: Stream.TransformOptions,
226-
): DecipherCCM | DecipherOCB | DecipherGCM | Decipher;
227+
): DecipherCCM | DecipherOCB | DecipherGCM | Decipheriv;
227228
export function createDecipheriv(
228229
algorithm: string,
229230
key: BinaryLikeNode,
@@ -233,12 +234,12 @@ export function createDecipheriv(
233234
| CipherOCBOptions
234235
| CipherGCMOptions
235236
| Stream.TransformOptions,
236-
): DecipherCCM | DecipherOCB | DecipherGCM | Decipher {
237-
return new Decipher(
237+
): DecipherCCM | DecipherOCB | DecipherGCM | Decipheriv {
238+
return new Decipheriv(
238239
algorithm,
239240
key,
240-
options as Record<string, TransformOptions>,
241241
iv,
242+
options as Record<string, TransformOptions>,
242243
);
243244
}
244245

@@ -265,7 +266,7 @@ export function createCipheriv(
265266
key: BinaryLikeNode,
266267
iv: BinaryLike,
267268
options?: Stream.TransformOptions,
268-
): CipherCCM | CipherOCB | CipherGCM | Cipher;
269+
): CipherCCM | CipherOCB | CipherGCM | Cipheriv;
269270
export function createCipheriv(
270271
algorithm: string,
271272
key: BinaryLikeNode,
@@ -275,11 +276,11 @@ export function createCipheriv(
275276
| CipherOCBOptions
276277
| CipherGCMOptions
277278
| Stream.TransformOptions,
278-
): CipherCCM | CipherOCB | CipherGCM | Cipher {
279-
return new Cipher(
279+
): CipherCCM | CipherOCB | CipherGCM | Cipheriv {
280+
return new Cipheriv(
280281
algorithm,
281282
key,
282-
options as Record<string, TransformOptions>,
283283
iv,
284+
options as Record<string, TransformOptions>,
284285
);
285286
}

0 commit comments

Comments
 (0)