Skip to content

Commit 5084d09

Browse files
authored
feat: add bytes methods and using embeded TextEncoder and TextDecoder (#95)
* feat: add bytes methods and using embeded TextEncoder and TextDecoder * chore: remove extra .js * chore: fix types
1 parent a72ffa3 commit 5084d09

File tree

34 files changed

+918
-156
lines changed

34 files changed

+918
-156
lines changed

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
## JSI
1111

1212

13-
If you want to use with `JSI` instead of `NativeModules` you need to set
13+
If you want to use with `NativeModules` instead of `JSI` you need to set
1414

1515
```typescript
1616
import RSA from "react-native-fast-rsa";
1717

18-
RSA.useJSI = true;
18+
RSA.useJSI = false;
1919
```
2020
if you need to use generate methods it is a good idea to disable it, because for now JSI will block your UI but it is faster compared to NativeModules
2121

@@ -78,15 +78,27 @@ class RSA {
7878
static decryptOAEP(message: string, label: string, hashName: Hash, privateKey: string): Promise<string>
7979
static decryptPKCS1v15(message: string, privateKey: string,): Promise<string>
8080

81+
static decryptOAEPBytes(message: Uint8Array, label: string, hashName: Hash, privateKey: string): Promise<Uint8Array>
82+
static decryptPKCS1v15Bytes(message: Uint8Array, privateKey: string,): Promise<Uint8Array>
83+
8184
static encryptOAEP(message: string,label: string, hashName: Hash, publicKey: string): Promise<string>
8285
static encryptPKCS1v15(message: string, publicKey: string): Promise<string>
8386

87+
static encryptOAEPBytes(message: Uint8Array,label: string, hashName: Hash, publicKey: string): Promise<Uint8Array>
88+
static encryptPKCS1v15Bytes(message: Uint8Array, publicKey: string): Promise<Uint8Array>
89+
8490
static signPSS(message: string, hashName: Hash, saltLengthName: SaltLength, privateKey: string): Promise<string>
8591
static signPKCS1v15(message: string, hashName: Hash, privateKey: string): Promise<string>
8692

93+
static signPSSBytes(message: Uint8Array, hashName: Hash, saltLengthName: SaltLength, privateKey: string): Promise<Uint8Array>
94+
static signPKCS1v15Bytes(message: Uint8Array, hashName: Hash, privateKey: string): Promise<Uint8Array>
95+
8796
static verifyPSS(signature: string, message: string, hashName: Hash, saltLengthName: SaltLength, publicKey: string): Promise<boolean>
8897
static verifyPKCS1v15(signature: string, message: string, hashName: Hash, publicKey: string): Promise<boolean>
8998

99+
static verifyPSSBytes(signature: Uint8Array, message: Uint8Array, hashName: Hash, saltLengthName: SaltLength, publicKey: string): Promise<boolean>
100+
static verifyPKCS1v15Bytes(signature: Uint8Array, message: Uint8Array, hashName: Hash, publicKey: string): Promise<boolean>
101+
90102
static hash(message: string, name: Hash): Promise<string>
91103
static base64(message: string): Promise<string>
92104

android/fast-rsa-adapter.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,97 @@ Java_com_fastrsa_FastRsaModule_callNative(JNIEnv* env,
9393
free(response);
9494

9595
return result;
96+
}
97+
98+
extern "C" JNIEXPORT jbyteArray JNICALL
99+
Java_com_fastrsa_FastRsaModule_encodeTextNative(JNIEnv* env, jobject thiz, jstring input, jstring encoding) {
100+
if (input == nullptr || encoding == nullptr) {
101+
jclass Exception = env->FindClass("java/lang/NullPointerException");
102+
env->ThrowNew(Exception, "Input parameters 'input' or 'encoding' cannot be null");
103+
return nullptr;
104+
}
105+
106+
// Convert Java Strings to C Strings
107+
const char* inputCStr = env->GetStringUTFChars(input, nullptr);
108+
const char* encodingCStr = env->GetStringUTFChars(encoding, nullptr);
109+
110+
if (inputCStr == nullptr || encodingCStr == nullptr) {
111+
jclass Exception = env->FindClass("java/lang/OutOfMemoryError");
112+
env->ThrowNew(Exception, "Failed to allocate memory for 'input' or 'encoding'");
113+
return nullptr;
114+
}
115+
116+
// Call the shared library function
117+
BytesReturn* response = RSAEncodeText(const_cast<char*>(inputCStr), const_cast<char*>(encodingCStr));
118+
119+
// Release allocated resources
120+
env->ReleaseStringUTFChars(input, inputCStr);
121+
env->ReleaseStringUTFChars(encoding, encodingCStr);
122+
123+
if (response->error != nullptr) {
124+
jclass Exception = env->FindClass("java/lang/Exception");
125+
env->ThrowNew(Exception, response->error);
126+
free(response);
127+
return nullptr;
128+
}
129+
130+
// Create a new byte array to return the encoded data
131+
jbyteArray result = env->NewByteArray(response->size);
132+
if (result == nullptr) {
133+
free(response);
134+
jclass Exception = env->FindClass("java/lang/OutOfMemoryError");
135+
env->ThrowNew(Exception, "Failed to allocate memory for result");
136+
return nullptr;
137+
}
138+
139+
env->SetByteArrayRegion(result, 0, response->size, reinterpret_cast<jbyte*>(response->message));
140+
free(response);
141+
142+
return result;
143+
}
144+
145+
extern "C" JNIEXPORT jstring JNICALL
146+
Java_com_fastrsa_FastRsaModule_decodeTextNative(JNIEnv* env, jobject thiz, jbyteArray input, jstring encoding,
147+
jint fatal, jint ignoreBOM, jint stream) {
148+
if (input == nullptr || encoding == nullptr) {
149+
jclass Exception = env->FindClass("java/lang/NullPointerException");
150+
env->ThrowNew(Exception, "Input parameters 'input' or 'encoding' cannot be null");
151+
return nullptr;
152+
}
153+
154+
// Convert Java Strings to C Strings
155+
const char* encodingCStr = env->GetStringUTFChars(encoding, nullptr);
156+
if (encodingCStr == nullptr) {
157+
jclass Exception = env->FindClass("java/lang/OutOfMemoryError");
158+
env->ThrowNew(Exception, "Failed to allocate memory for 'encoding'");
159+
return nullptr;
160+
}
161+
162+
// Convert Java byte array to C byte array
163+
jsize size = env->GetArrayLength(input);
164+
jbyte* inputBytes = env->GetByteArrayElements(input, nullptr);
165+
if (inputBytes == nullptr) {
166+
env->ReleaseStringUTFChars(encoding, encodingCStr);
167+
jclass Exception = env->FindClass("java/lang/OutOfMemoryError");
168+
env->ThrowNew(Exception, "Failed to allocate memory for 'input'");
169+
return nullptr;
170+
}
171+
172+
// Call the shared library function
173+
char* decodedString = RSADecodeText(inputBytes, size, const_cast<char*>(encodingCStr), fatal, ignoreBOM, stream);
174+
175+
// Release resources
176+
env->ReleaseStringUTFChars(encoding, encodingCStr);
177+
env->ReleaseByteArrayElements(input, inputBytes, JNI_ABORT);
178+
179+
if (decodedString == nullptr) {
180+
jclass Exception = env->FindClass("java/lang/Exception");
181+
env->ThrowNew(Exception, "Decoding failed");
182+
return nullptr;
183+
}
184+
185+
// Convert C string to Java string and return
186+
jstring result = env->NewStringUTF(decodedString);
187+
free(decodedString);
188+
return result;
96189
}

android/src/main/java/com/fastrsa/FastRsaModule.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ internal class FastRsaModule(reactContext: ReactApplicationContext) :
1111
external fun initialize(jsContext: Long)
1212
external fun destruct();
1313
external fun callNative(name: String, payload: ByteArray): ByteArray;
14+
external fun encodeTextNative(input: String, encoding: String): ByteArray
15+
external fun decodeTextNative(input: ByteArray, encoding: String, fatal: Int, ignoreBOM: Int, stream: Int): String
1416

1517
companion object {
1618
init {
@@ -41,6 +43,32 @@ internal class FastRsaModule(reactContext: ReactApplicationContext) :
4143
}.start()
4244
}
4345

46+
@ReactMethod(isBlockingSynchronousMethod = true)
47+
fun encodeText(input: String, encoding: String): WritableArray {
48+
return try {
49+
val result = encodeTextNative(input, encoding)
50+
Arguments.createArray().apply {
51+
result.forEach { byteValue: Byte -> pushInt(byteValue.toInt() and 0xFF) }
52+
}
53+
} catch (e: Exception) {
54+
Log.e(TAG, "Encoding error", e)
55+
throw RuntimeException("ENCODE_ERROR: Failed to encode text")
56+
}
57+
}
58+
59+
@ReactMethod(isBlockingSynchronousMethod = true)
60+
fun decodeText(input: ReadableArray, encoding: String, fatal: Boolean, ignoreBOM: Boolean, stream: Boolean): String {
61+
return try {
62+
val bytes = ByteArray(input.size()) { index ->
63+
input.getInt(index).toByte()
64+
}
65+
decodeTextNative(bytes, encoding, if (fatal) 1 else 0, if (ignoreBOM) 1 else 0, if (stream) 1 else 0)
66+
} catch (e: Exception) {
67+
Log.e(TAG, "Decoding error", e)
68+
throw RuntimeException("DECODE_ERROR: Failed to decode text")
69+
}
70+
}
71+
4472
@ReactMethod(isBlockingSynchronousMethod = true)
4573
fun install(): Boolean {
4674
Log.d(TAG, "Attempting to install JSI bindings...")

android/src/main/jniLibs/arm64-v8a/librsa_bridge.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ extern "C" {
8181
#endif
8282

8383
extern BytesReturn* RSABridgeCall(char* name, void* payload, int payloadSize);
84+
extern BytesReturn* RSAEncodeText(char* input, char* encoding);
85+
extern char* RSADecodeText(void* input, int size, char* encoding, int fatal, int ignoreBOM, int stream);
8486

8587
#ifdef __cplusplus
8688
}
557 KB
Binary file not shown.

android/src/main/jniLibs/armeabi-v7a/librsa_bridge.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ extern "C" {
8181
#endif
8282

8383
extern BytesReturn* RSABridgeCall(char* name, void* payload, int payloadSize);
84+
extern BytesReturn* RSAEncodeText(char* input, char* encoding);
85+
extern char* RSADecodeText(void* input, int size, char* encoding, int fatal, int ignoreBOM, int stream);
8486

8587
#ifdef __cplusplus
8688
}
656 KB
Binary file not shown.

android/src/main/jniLibs/x86/librsa_bridge.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ extern "C" {
8181
#endif
8282

8383
extern BytesReturn* RSABridgeCall(char* name, void* payload, int payloadSize);
84+
extern BytesReturn* RSAEncodeText(char* input, char* encoding);
85+
extern char* RSADecodeText(void* input, int size, char* encoding, int fatal, int ignoreBOM, int stream);
8486

8587
#ifdef __cplusplus
8688
}
637 KB
Binary file not shown.

android/src/main/jniLibs/x86_64/librsa_bridge.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ extern "C" {
8181
#endif
8282

8383
extern BytesReturn* RSABridgeCall(char* name, void* payload, int payloadSize);
84+
extern BytesReturn* RSAEncodeText(char* input, char* encoding);
85+
extern char* RSADecodeText(void* input, int size, char* encoding, int fatal, int ignoreBOM, int stream);
8486

8587
#ifdef __cplusplus
8688
}

0 commit comments

Comments
 (0)