Webcrypto Polyfill package#23
Webcrypto Polyfill package#23jaredperreault-okta wants to merge 23 commits intojp-react-native-sdkfrom
Conversation
…rectness, and architecture improvements Critical fixes: - Fix Android exportKey compilation error (undefined keyPair variable) - Fix Android importKey type mismatch (KeyPair vs KeyPairEntry) - Fix iOS silent failure in getRandomValues (now calls fatalError on CSPRNG failure) - Fix iOS importKey key size calculation (derive from modulus, not DER blob) - Fix iOS ASN.1 DER parsing with proper length decoding (replaces hardcoded offsets) - Fix iOS hardcoded exponent with parsed value from key data Security & safety: - Eliminate all force-unwrap (as!) casts in iOS via typed KeyEntry struct - Add synchronized blocks to all Android keyStore accesses for thread safety - Add key usage validation in JS verify() to match WebCrypto spec - JS getRandomValues validates returned length matches requested length Architecture: - Migrate bridge serialization from number[]/[NSNumber]/ReadableArray to Base64 strings across all layers (iOS, Android, TypeScript spec, JS polyfill), reducing serialization overhead from ~400% to ~33% - Extract iOS RSA DER parsing/construction into standalone RSAKeyUtils.swift for testability - Replace Android hand-rolled X.509 DER construction (~60 lines) with platform RSAPublicKeySpec - Remove dead code (getCryptoAlg), fix typos, clean up unused parameters Infrastructure: - Fix Jest config (testMatch pattern, setupFiles path, test import paths) - Add unit tests for digest, getRandomValues, importKey, verify, and polyfill installation - Update mocks to match Base64 bridge interface - Remove private:true flag, remove nonexistent ./cpp from files array - Update Android SDK defaults to 35
Harden native crypto bridge with security, correctness, and architecture improvements
FeiChen-okta
left a comment
There was a problem hiding this comment.
Left some comments for the android implementation.
|
|
||
| @ReactMethod(isBlockingSynchronousMethod = true) | ||
| fun randomUUID(): String { | ||
| return UUID.randomUUID().toString() |
Android module is on the wrong path. Add biometric auth and fix the android implementation by using android keystore.
update the android components.
| companion object { | ||
| const val NAME = "WebCryptoBridge" | ||
|
|
||
| private val cryptoKeys = mutableMapOf<String, CryptoKey>() |
There was a problem hiding this comment.
Move out of companion object. Reloading this module will keep this since the companion object survives reloads.
There was a problem hiding this comment.
Also do you need a remove method? to clean up keys that are not needed?
There was a problem hiding this comment.
Removal is an excellent question. The WebCrypto API doesn't have a concept of removal. For now I think the keys clearing when the app closes is good enough. Standard usage shouldn't result in more than a few keys
| promise: Promise | ||
| ) { | ||
| runCatching { | ||
| if (algorithm != "SHA-256") { |
There was a problem hiding this comment.
can we just remove algorithm as a parameter if it only support SHA-256? Allowing anything else will just lead to error anyways.
There was a problem hiding this comment.
This may support other algorithms in the future
|
|
||
| dependencies { | ||
| implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" | ||
| implementation 'com.facebook.react:react-native:+' |
There was a problem hiding this comment.
use a specific version to avoid supply chain risks.
There was a problem hiding this comment.
I attempted to address this, not sure if it did so successfully
Initial Setup of
@okta/react-native-platformMVP Impl of
@okta/react-native-webcrypto-bridge