Skip to content

Commit 412d20a

Browse files
committed
fix: EC raw key export and getCipherInfo name resolution
- Add raw format export for EC public keys (uncompressed point encoding) - Support 'raw' format in subtle.exportKey for EC keys - Fix getCipherInfo to use input name instead of cipher.getName() - Switch example dependency to workspace link
1 parent 31709ff commit 412d20a

5 files changed

Lines changed: 25 additions & 6 deletions

File tree

example/ios/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2811,7 +2811,7 @@ SPEC CHECKSUMS:
28112811
MMKVCore: f2dd4c9befea04277a55e84e7812f930537993df
28122812
NitroMmkv: afbc5b2fbf963be567c6c545aa1efcf6a9cec68e
28132813
NitroModules: 11bba9d065af151eae51e38a6425e04c3b223ff3
2814-
QuickCrypto: 91cda93ba3146b0cb92039d1058fbbaec100edd1
2814+
QuickCrypto: aad2c3dbe94e5eb4322d20e1bdccfa66464e2ae0
28152815
RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669
28162816
RCTDeprecation: c4b9e2fd0ab200e3af72b013ed6113187c607077
28172817
RCTRequired: e97dd5dafc1db8094e63bc5031e0371f092ae92a

example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"react-native-mmkv": "4.0.1",
4141
"react-native-nitro-modules": "0.33.2",
4242
"react-native-quick-base64": "2.2.2",
43-
"react-native-quick-crypto": "1.0.10",
43+
"react-native-quick-crypto": "workspace:*",
4444
"react-native-safe-area-context": "5.6.2",
4545
"react-native-screens": "4.18.0",
4646
"react-native-vector-icons": "10.3.0",

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ std::optional<CipherInfo> HybridCipher::getCipherInfo(const std::string& name, s
376376
}
377377
}
378378

379-
std::string name_str(cipher.getName());
379+
std::string name_str(name);
380380
std::transform(name_str.begin(), name_str.end(), name_str.begin(), ::tolower);
381381

382382
std::string mode_str(cipher.getModeLabel());

packages/react-native-quick-crypto/cpp/keys/HybridKeyObjectHandle.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,25 @@ std::shared_ptr<ArrayBuffer> HybridKeyObjectHandle::exportKey(std::optional<KFor
125125
}
126126
}
127127

128+
// For EC keys, handle raw format (uncompressed point)
129+
if (!format.has_value() && !type.has_value() && keyId == EVP_PKEY_EC && keyType == KeyType::PUBLIC) {
130+
const EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get());
131+
if (!ec_key)
132+
throw std::runtime_error("Failed to get EC key");
133+
const EC_GROUP* group = EC_KEY_get0_group(ec_key);
134+
const EC_POINT* point = EC_KEY_get0_public_key(ec_key);
135+
if (!group || !point)
136+
throw std::runtime_error("Failed to get EC public key");
137+
size_t len = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, nullptr);
138+
if (len == 0)
139+
throw std::runtime_error("Failed to get EC point size");
140+
std::vector<uint8_t> buf(len);
141+
if (EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, buf.data(), len, nullptr) == 0) {
142+
throw std::runtime_error("Failed to encode EC public key");
143+
}
144+
return ToNativeArrayBuffer(std::string(reinterpret_cast<const char*>(buf.data()), buf.size()));
145+
}
146+
128147
// Set default format and type if not provided
129148
auto exportFormat = format.value_or(KFormatType::DER);
130149
auto exportType = type.value_or(keyType == KeyType::PUBLIC ? KeyEncoding::SPKI : KeyEncoding::PKCS8);

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,12 @@ function getAlgorithmName(name: string, length: number): string {
113113
function ecExportKey(key: CryptoKey, format: KWebCryptoKeyFormat): ArrayBuffer {
114114
const keyObject = key.keyObject;
115115

116-
if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI) {
117-
// Export public key in SPKI format
116+
if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatRaw) {
117+
return bufferLikeToArrayBuffer(keyObject.handle.exportKey());
118+
} else if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI) {
118119
const exported = keyObject.export({ format: 'der', type: 'spki' });
119120
return bufferLikeToArrayBuffer(exported);
120121
} else if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8) {
121-
// Export private key in PKCS8 format
122122
const exported = keyObject.export({ format: 'der', type: 'pkcs8' });
123123
return bufferLikeToArrayBuffer(exported);
124124
} else {

0 commit comments

Comments
 (0)