expo-device-crypto 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/devicecrypto/{DeviceCryptoModule.kt → DeviceCrypto.kt} +17 -0
- package/build/DeviceCrypto.types.d.ts +5 -0
- package/build/DeviceCrypto.types.d.ts.map +1 -1
- package/build/DeviceCrypto.types.js.map +1 -1
- package/build/DeviceCryptoModule.d.ts.map +1 -1
- package/build/DeviceCryptoModule.js +1 -0
- package/build/DeviceCryptoModule.js.map +1 -1
- package/ios/DeviceCrypto.podspec +1 -1
- package/ios/DeviceCrypto.swift +29 -16
- package/package.json +6 -1
- package/src/DeviceCrypto.types.ts +5 -0
- package/src/DeviceCryptoModule.ts +1 -0
package/android/build.gradle
CHANGED
|
@@ -4,13 +4,13 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'expo.modules.devicecrypto'
|
|
7
|
-
version = '1.
|
|
7
|
+
version = '1.2.0'
|
|
8
8
|
|
|
9
9
|
android {
|
|
10
10
|
namespace "expo.modules.devicecrypto"
|
|
11
11
|
defaultConfig {
|
|
12
12
|
versionCode 1
|
|
13
|
-
versionName "1.
|
|
13
|
+
versionName "1.2.0"
|
|
14
14
|
}
|
|
15
15
|
lintOptions {
|
|
16
16
|
abortOnError false
|
package/android/src/main/java/expo/modules/devicecrypto/{DeviceCryptoModule.kt → DeviceCrypto.kt}
RENAMED
|
@@ -139,6 +139,7 @@ class DeviceCryptoModule : Module() {
|
|
|
139
139
|
alias: String,
|
|
140
140
|
digest: String?,
|
|
141
141
|
reqAuth: Boolean,
|
|
142
|
+
reqUnlocked: Boolean,
|
|
142
143
|
strongBox: Boolean): KeyPairGenerator {
|
|
143
144
|
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
|
|
144
145
|
KEY_ALGORITHM_EC,
|
|
@@ -154,6 +155,7 @@ class DeviceCryptoModule : Module() {
|
|
|
154
155
|
}
|
|
155
156
|
setIsStrongBoxBacked(strongBox)
|
|
156
157
|
setUserAuthenticationRequired(reqAuth)
|
|
158
|
+
setUnlockedDeviceRequired(reqUnlocked)
|
|
157
159
|
if (reqAuth) {
|
|
158
160
|
setUserAuthenticationParameters(
|
|
159
161
|
30, // 30 seconds
|
|
@@ -173,6 +175,7 @@ class DeviceCryptoModule : Module() {
|
|
|
173
175
|
padding: String?,
|
|
174
176
|
keySize: Int,
|
|
175
177
|
reqAuth: Boolean,
|
|
178
|
+
reqUnlocked: Boolean,
|
|
176
179
|
strongBox: Boolean): KeyPairGenerator {
|
|
177
180
|
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
|
|
178
181
|
KEY_ALGORITHM_RSA,
|
|
@@ -198,6 +201,7 @@ class DeviceCryptoModule : Module() {
|
|
|
198
201
|
setIsStrongBoxBacked(strongBox)
|
|
199
202
|
setKeySize(keySize)
|
|
200
203
|
setUserAuthenticationRequired(reqAuth)
|
|
204
|
+
setUnlockedDeviceRequired(reqUnlocked)
|
|
201
205
|
if (reqAuth) {
|
|
202
206
|
setUserAuthenticationParameters(
|
|
203
207
|
30, // 30 seconds
|
|
@@ -214,6 +218,7 @@ class DeviceCryptoModule : Module() {
|
|
|
214
218
|
alias: String,
|
|
215
219
|
digest: String?,
|
|
216
220
|
reqAuth: Boolean,
|
|
221
|
+
reqUnlocked: Boolean,
|
|
217
222
|
strongBox: Boolean): KeyPairGenerator {
|
|
218
223
|
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
|
|
219
224
|
KEY_ALGORITHM_EC,
|
|
@@ -229,6 +234,7 @@ class DeviceCryptoModule : Module() {
|
|
|
229
234
|
}
|
|
230
235
|
setIsStrongBoxBacked(strongBox)
|
|
231
236
|
setUserAuthenticationRequired(reqAuth)
|
|
237
|
+
setUnlockedDeviceRequired(reqUnlocked)
|
|
232
238
|
if (reqAuth) {
|
|
233
239
|
setUserAuthenticationParameters(
|
|
234
240
|
30, // 30 seconds
|
|
@@ -305,6 +311,7 @@ class DeviceCryptoModule : Module() {
|
|
|
305
311
|
|
|
306
312
|
private fun generateKeyPair(alias: String, o: Map<String, Any?>): GenerateKeyPairResult {
|
|
307
313
|
val reqAuth = o["reqAuth"] as Boolean
|
|
314
|
+
val reqUnlocked = o["reqUnlocked"] as Boolean
|
|
308
315
|
if (reqAuth && isAuthCheckAvailable() != AuthCheckResult.AVAILABLE) {
|
|
309
316
|
throw Exception("NO_AUTH_AVAILABLE")
|
|
310
317
|
}
|
|
@@ -324,6 +331,7 @@ class DeviceCryptoModule : Module() {
|
|
|
324
331
|
alias = alias,
|
|
325
332
|
digest = DIGEST_SHA256,
|
|
326
333
|
reqAuth = reqAuth,
|
|
334
|
+
reqUnlocked = reqUnlocked,
|
|
327
335
|
strongBox = strongBox
|
|
328
336
|
)
|
|
329
337
|
AlgorithmType.RSA_2048_PKCS1 -> buildRSA(
|
|
@@ -333,6 +341,7 @@ class DeviceCryptoModule : Module() {
|
|
|
333
341
|
padding = ENCRYPTION_PADDING_RSA_PKCS1,
|
|
334
342
|
keySize = 2048,
|
|
335
343
|
reqAuth = reqAuth,
|
|
344
|
+
reqUnlocked = reqUnlocked,
|
|
336
345
|
strongBox = strongBox
|
|
337
346
|
)
|
|
338
347
|
AlgorithmType.RSA_2048_OAEP_SHA1 -> buildRSA(
|
|
@@ -342,6 +351,7 @@ class DeviceCryptoModule : Module() {
|
|
|
342
351
|
padding = ENCRYPTION_PADDING_RSA_OAEP,
|
|
343
352
|
keySize = 2048,
|
|
344
353
|
reqAuth = reqAuth,
|
|
354
|
+
reqUnlocked = reqUnlocked,
|
|
345
355
|
strongBox = strongBox
|
|
346
356
|
)
|
|
347
357
|
AlgorithmType.RSA_4096_PKCS1 -> buildRSA(
|
|
@@ -351,6 +361,7 @@ class DeviceCryptoModule : Module() {
|
|
|
351
361
|
padding = ENCRYPTION_PADDING_RSA_PKCS1,
|
|
352
362
|
keySize = 4096,
|
|
353
363
|
reqAuth = reqAuth,
|
|
364
|
+
reqUnlocked = reqUnlocked,
|
|
354
365
|
strongBox = strongBox
|
|
355
366
|
)
|
|
356
367
|
AlgorithmType.RSA_4096_OAEP_SHA1 -> buildRSA(
|
|
@@ -360,12 +371,14 @@ class DeviceCryptoModule : Module() {
|
|
|
360
371
|
padding = ENCRYPTION_PADDING_RSA_OAEP,
|
|
361
372
|
keySize = 4096,
|
|
362
373
|
reqAuth = reqAuth,
|
|
374
|
+
reqUnlocked = reqUnlocked,
|
|
363
375
|
strongBox = strongBox
|
|
364
376
|
)
|
|
365
377
|
AlgorithmType.ECIES_P256_AES256_GCM -> buildECIES(
|
|
366
378
|
alias = alias,
|
|
367
379
|
digest = null,
|
|
368
380
|
reqAuth = reqAuth,
|
|
381
|
+
reqUnlocked = reqUnlocked,
|
|
369
382
|
strongBox = strongBox
|
|
370
383
|
)
|
|
371
384
|
AlgorithmType.RSA_SHA256 -> buildRSA(
|
|
@@ -375,6 +388,7 @@ class DeviceCryptoModule : Module() {
|
|
|
375
388
|
padding = SIGNATURE_PADDING_RSA_PKCS1,
|
|
376
389
|
keySize = 2048,
|
|
377
390
|
reqAuth = reqAuth,
|
|
391
|
+
reqUnlocked = reqUnlocked,
|
|
378
392
|
strongBox = strongBox
|
|
379
393
|
)
|
|
380
394
|
AlgorithmType.RSA_SHA256_PSS -> buildRSA(
|
|
@@ -384,6 +398,7 @@ class DeviceCryptoModule : Module() {
|
|
|
384
398
|
padding = SIGNATURE_PADDING_RSA_PSS,
|
|
385
399
|
keySize = 2048,
|
|
386
400
|
reqAuth = reqAuth,
|
|
401
|
+
reqUnlocked = reqUnlocked,
|
|
387
402
|
strongBox = strongBox
|
|
388
403
|
)
|
|
389
404
|
AlgorithmType.RSA_4096_SHA256 -> buildRSA(
|
|
@@ -393,6 +408,7 @@ class DeviceCryptoModule : Module() {
|
|
|
393
408
|
padding = SIGNATURE_PADDING_RSA_PKCS1,
|
|
394
409
|
keySize = 4096,
|
|
395
410
|
reqAuth = reqAuth,
|
|
411
|
+
reqUnlocked = reqUnlocked,
|
|
396
412
|
strongBox = strongBox
|
|
397
413
|
)
|
|
398
414
|
AlgorithmType.RSA_4096_SHA256_PSS -> buildRSA(
|
|
@@ -402,6 +418,7 @@ class DeviceCryptoModule : Module() {
|
|
|
402
418
|
padding = SIGNATURE_PADDING_RSA_PSS,
|
|
403
419
|
keySize = 4096,
|
|
404
420
|
reqAuth = reqAuth,
|
|
421
|
+
reqUnlocked = reqUnlocked,
|
|
405
422
|
strongBox = strongBox
|
|
406
423
|
)
|
|
407
424
|
else -> throw Exception("INVALID_ALGORITHM_TYPE")
|
|
@@ -64,6 +64,11 @@ export type GenerateKeyPairOptions = {
|
|
|
64
64
|
* @platform android 🤖
|
|
65
65
|
*/
|
|
66
66
|
preferStrongBox?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Whether to require the device to be unlocked to use the key pair.
|
|
69
|
+
* @default true
|
|
70
|
+
*/
|
|
71
|
+
requireUnlockedDevice?: boolean;
|
|
67
72
|
};
|
|
68
73
|
type BaseAuthOptions = {
|
|
69
74
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceCrypto.types.d.ts","sourceRoot":"","sources":["../src/DeviceCrypto.types.ts"],"names":[],"mappings":"AAAA,oBAAY,qBAAqB;IAC/B,kBAAkB,uBAAuB;IACzC,uBAAuB,4BAA4B;IACnD,aAAa,kBAAkB;CAChC;AAED,oBAAY,eAAe;IACzB,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;CAC5B;AAED,oBAAY,UAAU;IACpB,QAAQ,aAAa;IACrB,qBAAqB,0BAA0B;CAChD;AAED,oBAAY,gBAAgB;IAC1B,sBAAsB,2BAA2B;IACjD,UAAU,eAAe;IACzB,cAAc,mBAAmB;IACjC,eAAe,oBAAoB;IACnC,mBAAmB,wBAAwB;CAC5C;AAED,oBAAY,mBAAmB;IAC7B,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;IACzC,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;IACzC,qBAAqB,0BAA0B;CAChD;AAED,KAAK,cAAc,GAAG,mBAAmB,CAAC,qBAAqB,CAAC;AAChE,KAAK,YAAY,GACb,mBAAmB,CAAC,cAAc,GAClC,mBAAmB,CAAC,kBAAkB,GACtC,mBAAmB,CAAC,cAAc,GAClC,mBAAmB,CAAC,kBAAkB,CAAC;AAE3C,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,aAAa,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IACtD;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"DeviceCrypto.types.d.ts","sourceRoot":"","sources":["../src/DeviceCrypto.types.ts"],"names":[],"mappings":"AAAA,oBAAY,qBAAqB;IAC/B,kBAAkB,uBAAuB;IACzC,uBAAuB,4BAA4B;IACnD,aAAa,kBAAkB;CAChC;AAED,oBAAY,eAAe;IACzB,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;CAC5B;AAED,oBAAY,UAAU;IACpB,QAAQ,aAAa;IACrB,qBAAqB,0BAA0B;CAChD;AAED,oBAAY,gBAAgB;IAC1B,sBAAsB,2BAA2B;IACjD,UAAU,eAAe;IACzB,cAAc,mBAAmB;IACjC,eAAe,oBAAoB;IACnC,mBAAmB,wBAAwB;CAC5C;AAED,oBAAY,mBAAmB;IAC7B,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;IACzC,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;IACzC,qBAAqB,0BAA0B;CAChD;AAED,KAAK,cAAc,GAAG,mBAAmB,CAAC,qBAAqB,CAAC;AAChE,KAAK,YAAY,GACb,mBAAmB,CAAC,cAAc,GAClC,mBAAmB,CAAC,kBAAkB,GACtC,mBAAmB,CAAC,cAAc,GAClC,mBAAmB,CAAC,kBAAkB,CAAC;AAE3C,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,aAAa,EAAE,gBAAgB,GAAG,mBAAmB,CAAC;IACtD;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB;;OAEG;IACH,aAAa,EAAE,gBAAgB,CAAC;CACjC,CAAC;AACF,KAAK,iBAAiB,GAAG,kBAAkB,CAAC;AAE5C,KAAK,wBAAwB,GAAG;IAC9B;;OAEG;IACH,aAAa,EAAE,YAAY,CAAC;CAC7B,CAAC;AACF,KAAK,wBAAwB,GAAG,wBAAwB,CAAC;AAEzD,KAAK,0BAA0B,GAAG;IAChC;;OAEG;IACH,aAAa,EAAE,cAAc,CAAC;IAC9B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AACF,KAAK,0BAA0B,GAAG,0BAA0B,CAAC;AAE7D,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAC/D,MAAM,MAAM,aAAa,GAAG,iBAAiB,CAAC;AAE9C,MAAM,MAAM,cAAc,GACtB,CAAC,eAAe,GAAG,0BAA0B,CAAC,GAC9C,CAAC,eAAe,GAAG,wBAAwB,CAAC,CAAC;AACjD,MAAM,MAAM,cAAc,GACtB,CAAC,eAAe,GAAG,0BAA0B,CAAC,GAC9C,wBAAwB,CAAC;AAE7B,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceCrypto.types.js","sourceRoot":"","sources":["../src/DeviceCrypto.types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,kEAAyC,CAAA;IACzC,4EAAmD,CAAA;IACnD,wDAA+B,CAAA;AACjC,CAAC,EAJW,qBAAqB,KAArB,qBAAqB,QAIhC;AAED,MAAM,CAAN,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,0CAAuB,CAAA;IACvB,8CAA2B,CAAA;IAC3B,8CAA2B,CAAA;AAC7B,CAAC,EAJW,eAAe,KAAf,eAAe,QAI1B;AAED,MAAM,CAAN,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,mCAAqB,CAAA;IACrB,6DAA+C,CAAA;AACjD,CAAC,EAHW,UAAU,KAAV,UAAU,QAGrB;AAED,MAAM,CAAN,IAAY,gBAMX;AAND,WAAY,gBAAgB;IAC1B,qEAAiD,CAAA;IACjD,6CAAyB,CAAA;IACzB,qDAAiC,CAAA;IACjC,uDAAmC,CAAA;IACnC,+DAA2C,CAAA;AAC7C,CAAC,EANW,gBAAgB,KAAhB,gBAAgB,QAM3B;AAED,MAAM,CAAN,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC7B,wDAAiC,CAAA;IACjC,gEAAyC,CAAA;IACzC,wDAAiC,CAAA;IACjC,gEAAyC,CAAA;IACzC,sEAA+C,CAAA;AACjD,CAAC,EANW,mBAAmB,KAAnB,mBAAmB,QAM9B","sourcesContent":["export enum GenerateKeyPairResult {\n KEY_PAIR_GENERATED = \"KEY_PAIR_GENERATED\",\n KEY_PAIR_ALREADY_EXISTS = \"KEY_PAIR_ALREADY_EXISTS\",\n NOT_AVAILABLE = \"NOT_AVAILABLE\",\n}\n\nexport enum AuthCheckResult {\n AVAILABLE = \"AVAILABLE\",\n NO_HARDWARE = \"NO_HARDWARE\",\n UNAVAILABLE = \"UNAVAILABLE\",\n}\n\nexport enum AuthMethod {\n PASSCODE = \"PASSCODE\",\n PASSCODE_OR_BIOMETRIC = \"PASSCODE_OR_BIOMETRIC\",\n}\n\nexport enum SigningAlgorithm {\n ECDSA_SECP256R1_SHA256 = \"ECDSA_SECP256R1_SHA256\",\n RSA_SHA256 = \"RSA_SHA256\",\n RSA_SHA256_PSS = \"RSA_SHA256_PSS\",\n RSA_4096_SHA256 = \"RSA_4096_SHA256\",\n RSA_4096_SHA256_PSS = \"RSA_4096_SHA256_PSS\",\n}\n\nexport enum EncryptionAlgorithm {\n RSA_2048_PKCS1 = \"RSA_2048_PKCS1\",\n RSA_2048_OAEP_SHA1 = \"RSA_2048_OAEP_SHA1\",\n RSA_4096_PKCS1 = \"RSA_4096_PKCS1\",\n RSA_4096_OAEP_SHA1 = \"RSA_4096_OAEP_SHA1\",\n ECIES_P256_AES256_GCM = \"ECIES_P256_AES256_GCM\",\n}\n\ntype EciesAlgorithm = EncryptionAlgorithm.ECIES_P256_AES256_GCM;\ntype RsaAlgorithm =\n | EncryptionAlgorithm.RSA_2048_PKCS1\n | EncryptionAlgorithm.RSA_2048_OAEP_SHA1\n | EncryptionAlgorithm.RSA_4096_PKCS1\n | EncryptionAlgorithm.RSA_4096_OAEP_SHA1;\n\nexport type GenerateKeyPairOptions = {\n /**\n * The algorithm type of the key to generate.\n */\n algorithmType: SigningAlgorithm | EncryptionAlgorithm;\n /**\n * Whether to require authentication to sign.\n * Setting this to true will prompt biometric or passcode authentication before signing.\n *\n * Please check the *`isAuthCheckAvailable`* function to see if authentication is available.\n * If authentication is not available, generating a key pair will throw an error.\n * @default false\n */\n requireAuthentication?: boolean;\n /**\n * The method of authentication to use.\n * Note that on Android you have to define it when signing or decrypting.\n *\n * If you want to allow to use Face ID, you need to add the following to your app.json config file:\n * ```json\n * \"ios\": {\n * \"infoPlist\": {\n * \"NSFaceIDUsageDescription\": \"We use Face ID to secure your data.\",\n * }\n * }\n * ```\n * @default AuthMethod.PASSCODE_OR_BIOMETRIC\n * @platform ios 🍏\n */\n authMethod?: AuthMethod;\n /**\n * If the Strong Box is available, it will be used instead of the Trusted Execution Environment (TEE).\n * @default false\n * @platform android 🤖\n */\n preferStrongBox?: boolean;\n};\n\ntype BaseAuthOptions = {\n /**\n * The title of the prompt to show when authentication is required.\n * @default \"Unlock\"\n * @platform android 🤖\n */\n promptTitle?: string;\n /**\n * The subtitle of the prompt to show when authentication is required.\n * @default \"Enter your PIN to continue\"\n * @platform android 🤖\n */\n promptSubtitle?: string;\n /**\n * The method of authentication to use.\n * Note that on iOS you have to define it when generating the key pair.\n * @default AuthMethod.PASSCODE_OR_BIOMETRIC\n * @platform android 🤖\n */\n authMethod?: AuthMethod;\n};\n\ntype BaseSigningOptions = {\n /**\n * The algorithm type of the key to use for signing.\n */\n algorithmType: SigningAlgorithm;\n};\ntype BaseVerifyOptions = BaseSigningOptions;\n\ntype BaseRsaEncryptionOptions = {\n /**\n * The algorithm type of the key to use for encrypting.\n */\n algorithmType: RsaAlgorithm;\n};\ntype BaseRsaDecryptionOptions = BaseRsaEncryptionOptions;\n\ntype BaseEciesEncryptionOptions = {\n /**\n * The algorithm type of the key to use for encrypting.\n */\n algorithmType: EciesAlgorithm;\n /**\n * The peer public key to use for ECIES.\n */\n peerPublicKey: string;\n};\ntype BaseEciesDecryptionOptions = BaseEciesEncryptionOptions;\n\nexport type SignOptions = BaseAuthOptions & BaseSigningOptions;\nexport type VerifyOptions = BaseVerifyOptions;\n\nexport type DecryptOptions =\n | (BaseAuthOptions & BaseEciesDecryptionOptions)\n | (BaseAuthOptions & BaseRsaDecryptionOptions);\nexport type EncryptOptions =\n | (BaseAuthOptions & BaseEciesEncryptionOptions)\n | BaseRsaEncryptionOptions;\n\nexport interface GetPublicKeyOptions {\n /**\n * The format of the public key to return.\n * @default \"PEM\" (Base64 of PEM-encoded SubjectPublicKeyInfo (SPKI) for P‑256)\n */\n format?: \"PEM\" | \"BASE64\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DeviceCrypto.types.js","sourceRoot":"","sources":["../src/DeviceCrypto.types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,kEAAyC,CAAA;IACzC,4EAAmD,CAAA;IACnD,wDAA+B,CAAA;AACjC,CAAC,EAJW,qBAAqB,KAArB,qBAAqB,QAIhC;AAED,MAAM,CAAN,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,0CAAuB,CAAA;IACvB,8CAA2B,CAAA;IAC3B,8CAA2B,CAAA;AAC7B,CAAC,EAJW,eAAe,KAAf,eAAe,QAI1B;AAED,MAAM,CAAN,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,mCAAqB,CAAA;IACrB,6DAA+C,CAAA;AACjD,CAAC,EAHW,UAAU,KAAV,UAAU,QAGrB;AAED,MAAM,CAAN,IAAY,gBAMX;AAND,WAAY,gBAAgB;IAC1B,qEAAiD,CAAA;IACjD,6CAAyB,CAAA;IACzB,qDAAiC,CAAA;IACjC,uDAAmC,CAAA;IACnC,+DAA2C,CAAA;AAC7C,CAAC,EANW,gBAAgB,KAAhB,gBAAgB,QAM3B;AAED,MAAM,CAAN,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC7B,wDAAiC,CAAA;IACjC,gEAAyC,CAAA;IACzC,wDAAiC,CAAA;IACjC,gEAAyC,CAAA;IACzC,sEAA+C,CAAA;AACjD,CAAC,EANW,mBAAmB,KAAnB,mBAAmB,QAM9B","sourcesContent":["export enum GenerateKeyPairResult {\n KEY_PAIR_GENERATED = \"KEY_PAIR_GENERATED\",\n KEY_PAIR_ALREADY_EXISTS = \"KEY_PAIR_ALREADY_EXISTS\",\n NOT_AVAILABLE = \"NOT_AVAILABLE\",\n}\n\nexport enum AuthCheckResult {\n AVAILABLE = \"AVAILABLE\",\n NO_HARDWARE = \"NO_HARDWARE\",\n UNAVAILABLE = \"UNAVAILABLE\",\n}\n\nexport enum AuthMethod {\n PASSCODE = \"PASSCODE\",\n PASSCODE_OR_BIOMETRIC = \"PASSCODE_OR_BIOMETRIC\",\n}\n\nexport enum SigningAlgorithm {\n ECDSA_SECP256R1_SHA256 = \"ECDSA_SECP256R1_SHA256\",\n RSA_SHA256 = \"RSA_SHA256\",\n RSA_SHA256_PSS = \"RSA_SHA256_PSS\",\n RSA_4096_SHA256 = \"RSA_4096_SHA256\",\n RSA_4096_SHA256_PSS = \"RSA_4096_SHA256_PSS\",\n}\n\nexport enum EncryptionAlgorithm {\n RSA_2048_PKCS1 = \"RSA_2048_PKCS1\",\n RSA_2048_OAEP_SHA1 = \"RSA_2048_OAEP_SHA1\",\n RSA_4096_PKCS1 = \"RSA_4096_PKCS1\",\n RSA_4096_OAEP_SHA1 = \"RSA_4096_OAEP_SHA1\",\n ECIES_P256_AES256_GCM = \"ECIES_P256_AES256_GCM\",\n}\n\ntype EciesAlgorithm = EncryptionAlgorithm.ECIES_P256_AES256_GCM;\ntype RsaAlgorithm =\n | EncryptionAlgorithm.RSA_2048_PKCS1\n | EncryptionAlgorithm.RSA_2048_OAEP_SHA1\n | EncryptionAlgorithm.RSA_4096_PKCS1\n | EncryptionAlgorithm.RSA_4096_OAEP_SHA1;\n\nexport type GenerateKeyPairOptions = {\n /**\n * The algorithm type of the key to generate.\n */\n algorithmType: SigningAlgorithm | EncryptionAlgorithm;\n /**\n * Whether to require authentication to sign.\n * Setting this to true will prompt biometric or passcode authentication before signing.\n *\n * Please check the *`isAuthCheckAvailable`* function to see if authentication is available.\n * If authentication is not available, generating a key pair will throw an error.\n * @default false\n */\n requireAuthentication?: boolean;\n /**\n * The method of authentication to use.\n * Note that on Android you have to define it when signing or decrypting.\n *\n * If you want to allow to use Face ID, you need to add the following to your app.json config file:\n * ```json\n * \"ios\": {\n * \"infoPlist\": {\n * \"NSFaceIDUsageDescription\": \"We use Face ID to secure your data.\",\n * }\n * }\n * ```\n * @default AuthMethod.PASSCODE_OR_BIOMETRIC\n * @platform ios 🍏\n */\n authMethod?: AuthMethod;\n /**\n * If the Strong Box is available, it will be used instead of the Trusted Execution Environment (TEE).\n * @default false\n * @platform android 🤖\n */\n preferStrongBox?: boolean;\n /**\n * Whether to require the device to be unlocked to use the key pair.\n * @default true\n */\n requireUnlockedDevice?: boolean;\n};\n\ntype BaseAuthOptions = {\n /**\n * The title of the prompt to show when authentication is required.\n * @default \"Unlock\"\n * @platform android 🤖\n */\n promptTitle?: string;\n /**\n * The subtitle of the prompt to show when authentication is required.\n * @default \"Enter your PIN to continue\"\n * @platform android 🤖\n */\n promptSubtitle?: string;\n /**\n * The method of authentication to use.\n * Note that on iOS you have to define it when generating the key pair.\n * @default AuthMethod.PASSCODE_OR_BIOMETRIC\n * @platform android 🤖\n */\n authMethod?: AuthMethod;\n};\n\ntype BaseSigningOptions = {\n /**\n * The algorithm type of the key to use for signing.\n */\n algorithmType: SigningAlgorithm;\n};\ntype BaseVerifyOptions = BaseSigningOptions;\n\ntype BaseRsaEncryptionOptions = {\n /**\n * The algorithm type of the key to use for encrypting.\n */\n algorithmType: RsaAlgorithm;\n};\ntype BaseRsaDecryptionOptions = BaseRsaEncryptionOptions;\n\ntype BaseEciesEncryptionOptions = {\n /**\n * The algorithm type of the key to use for encrypting.\n */\n algorithmType: EciesAlgorithm;\n /**\n * The peer public key to use for ECIES.\n */\n peerPublicKey: string;\n};\ntype BaseEciesDecryptionOptions = BaseEciesEncryptionOptions;\n\nexport type SignOptions = BaseAuthOptions & BaseSigningOptions;\nexport type VerifyOptions = BaseVerifyOptions;\n\nexport type DecryptOptions =\n | (BaseAuthOptions & BaseEciesDecryptionOptions)\n | (BaseAuthOptions & BaseRsaDecryptionOptions);\nexport type EncryptOptions =\n | (BaseAuthOptions & BaseEciesEncryptionOptions)\n | BaseRsaEncryptionOptions;\n\nexport interface GetPublicKeyOptions {\n /**\n * The format of the public key to return.\n * @default \"PEM\" (Base64 of PEM-encoded SubjectPublicKeyInfo (SPKI) for P‑256)\n */\n format?: \"PEM\" | \"BASE64\";\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceCryptoModule.d.ts","sourceRoot":"","sources":["../src/DeviceCryptoModule.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EAEnB,WAAW,EACX,cAAc,EACd,aAAa,EAEb,cAAc,EAEf,MAAM,sBAAsB,CAAC;;IA8B5B;;;OAGG;gCAvBqB,eAAe;IAyBvC;;;;OAIG;gCA5BqB,OAAO;IA8B/B;;;;OAIG;6BAC4B,MAAM,YAAY,sBAAsB;
|
|
1
|
+
{"version":3,"file":"DeviceCryptoModule.d.ts","sourceRoot":"","sources":["../src/DeviceCryptoModule.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EAEnB,WAAW,EACX,cAAc,EACd,aAAa,EAEb,cAAc,EAEf,MAAM,sBAAsB,CAAC;;IA8B5B;;;OAGG;gCAvBqB,eAAe;IAyBvC;;;;OAIG;gCA5BqB,OAAO;IA8B/B;;;;OAIG;6BAC4B,MAAM,YAAY,sBAAsB;IAUvE;;;;;OAKG;0BACmB,MAAM,YAAY,mBAAmB;IAW3D;;;;OAIG;2BA/DkB,MAAM,KAAG,OAAO;IAiErC;;;OAGG;mBAnEQ,MAAM,EAAE;IAqEnB;;;;;;OAMG;kBACiB,MAAM,QAAQ,MAAM,YAAY,WAAW;IAU/D;;;;;;;OAOG;oBAEM,MAAM,QACP,MAAM,aACD,MAAM,YACP,aAAa;IAQzB;;;;;;;;;OASG;qBACoB,MAAM,QAAQ,MAAM,YAAY,cAAc;IAcrE;;;;;;OAMG;qBACoB,MAAM,QAAQ,MAAM,YAAY,cAAc;;AA3HvE,wBAsIE"}
|
|
@@ -29,6 +29,7 @@ export default {
|
|
|
29
29
|
reqAuth: options?.requireAuthentication ?? false,
|
|
30
30
|
authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,
|
|
31
31
|
preferStrongBox: options?.preferStrongBox ?? false,
|
|
32
|
+
reqUnlocked: options?.requireUnlockedDevice ?? true,
|
|
32
33
|
};
|
|
33
34
|
return module.generateKeyPair(alias, o);
|
|
34
35
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceCryptoModule.js","sourceRoot":"","sources":["../src/DeviceCryptoModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,MAAM,CAAC;AAEzD,OAAO,EAKL,UAAU,EAIV,gBAAgB,EAEhB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,SAAS,WAAW,CAAC,MAAc,EAAE,KAAK,GAAG,MAAM;IACjD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAE/D,OAAO,cAAc,KAAK,UAAU,OAAO,cAAc,KAAK,SAAS,CAAC;AAC1E,CAAC;AAoBD,MAAM,MAAM,GAAG,mBAAmB,CAAqB,cAAc,CAAC,CAAC;AAEvE,eAAe;IACb;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;IACjD;;;;OAIG;IACH,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;IACjD;;;;OAIG;IACH,eAAe,EAAE,KAAK,EAAE,KAAa,EAAE,OAAgC,EAAE,EAAE;QACzE,MAAM,CAAC,GAAG;YACR,QAAQ,EAAE,OAAO,EAAE,aAAa;YAChC,OAAO,EAAE,OAAO,EAAE,qBAAqB,IAAI,KAAK;YAChD,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,UAAU,CAAC,qBAAqB;YACnE,eAAe,EAAE,OAAO,EAAE,eAAe,IAAI,KAAK;
|
|
1
|
+
{"version":3,"file":"DeviceCryptoModule.js","sourceRoot":"","sources":["../src/DeviceCryptoModule.ts"],"names":[],"mappings":"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","sourcesContent":["import { NativeModule, requireNativeModule } from \"expo\";\n\nimport {\n AuthCheckResult,\n GenerateKeyPairOptions,\n GenerateKeyPairResult,\n GetPublicKeyOptions,\n AuthMethod,\n SignOptions,\n DecryptOptions,\n VerifyOptions,\n SigningAlgorithm,\n EncryptOptions,\n EncryptionAlgorithm,\n} from \"./DeviceCrypto.types\";\n\nfunction base64ToPem(base64: string, label = \"DATA\") {\n const normalized = base64.replace(/\\s+/g, \"\");\n const wrapped = normalized.match(/.{1,64}/g)?.join(\"\\n\") ?? \"\";\n\n return `-----BEGIN ${label}-----\\n${wrapped}\\n-----END ${label}-----\\n`;\n}\n\ndeclare class DeviceCryptoModule extends NativeModule {\n isAuthCheckAvailable(): AuthCheckResult;\n isStrongBoxAvailable(): boolean;\n generateKeyPair(alias: string, o: any): GenerateKeyPairResult;\n getPublicKey(alias: string): string | null;\n removeKeyPair(alias: string): boolean;\n aliases(): string[];\n sign(alias: string, data: string, o: any): Promise<string | null>;\n verify(\n alias: string,\n data: string,\n signature: string,\n o: any\n ): boolean | null;\n encrypt(alias: string, data: string, o: any): Promise<string | null>;\n decrypt(alias: string, data: string, o: any): Promise<string | null>;\n}\n\nconst module = requireNativeModule<DeviceCryptoModule>(\"DeviceCrypto\");\n\nexport default {\n /**\n * Checks if the biometric or passcode authentication is available.\n * @returns The result of the operation.\n */\n isAuthCheckAvailable: module.isAuthCheckAvailable,\n /**\n * Checks if the strong box is available .\n * @returns The result of the operation.\n * @platform android 🤖\n */\n isStrongBoxAvailable: module.isStrongBoxAvailable,\n /**\n * Creates a new ECDSA P‑256 key pair for the given alias, if it doesn’t already exist.\n * @param alias - The alias to use for the key pair.\n * @returns The result of the operation.\n */\n generateKeyPair: async (alias: string, options?: GenerateKeyPairOptions) => {\n const o = {\n algoType: options?.algorithmType,\n reqAuth: options?.requireAuthentication ?? false,\n authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,\n preferStrongBox: options?.preferStrongBox ?? false,\n reqUnlocked: options?.requireUnlockedDevice ?? true,\n };\n return module.generateKeyPair(alias, o);\n },\n /**\n * Returns the public key for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param options - The options for the operation.\n * @returns The public key.\n */\n getPublicKey: (alias: string, options?: GetPublicKeyOptions) => {\n const publicKey = module.getPublicKey(alias);\n if (!publicKey) return null;\n if (options?.format === \"PEM\") {\n return base64ToPem(publicKey, \"PUBLIC KEY\");\n } else if (options?.format === \"BASE64\") {\n return publicKey;\n }\n\n return base64ToPem(publicKey, \"PUBLIC KEY\");\n },\n /**\n * Removes the key pair for the given alias.\n * @param alias - The alias to use for the key pair.\n * @returns True if the key pair was removed, false otherwise.\n */\n removeKeyPair: module.removeKeyPair,\n /**\n * Lists the aliases for the key pairs.\n * @returns The aliases.\n */\n aliases: module.aliases,\n /**\n * Signs the given data with the private key for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param data - The data to sign.\n * @param options - The options for the operation.\n * @returns The signature.\n */\n sign: async (alias: string, data: string, options?: SignOptions) => {\n const o = {\n title: options?.promptTitle ?? \"Unlock\",\n subtitle: options?.promptSubtitle ?? \"Enter your PIN to continue\",\n authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,\n algoType:\n options?.algorithmType ?? SigningAlgorithm.ECDSA_SECP256R1_SHA256,\n };\n return module.sign(alias, data, o);\n },\n /**\n * Verifies the given data with the signature for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param data - The data to verify in UTF-8 format.\n * @param signature - The signature to verify in Base64 format.\n * @param options - The options for the operation.\n * @returns True if the signature is valid, false otherwise.\n */\n verify: async (\n alias: string,\n data: string,\n signature: string,\n options?: VerifyOptions\n ) => {\n const o = {\n algoType:\n options?.algorithmType ?? SigningAlgorithm.ECDSA_SECP256R1_SHA256,\n };\n return module.verify(alias, data, signature, o);\n },\n /**\n * Signs the given data with the private key for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param data - The data to sign in UTF-8 format.\n * @param options - The options for the operation.\n * @default {\n * algoType: EncryptionAlgorithm.RSA_2048_PKCS1,\n * }\n * @returns The signature.\n */\n encrypt: async (alias: string, data: string, options?: EncryptOptions) => {\n const o = {\n algoType: options?.algorithmType ?? EncryptionAlgorithm.RSA_2048_PKCS1,\n // @ts-ignore\n title: options?.promptTitle ?? \"Unlock\",\n // @ts-ignore\n subtitle: options?.promptSubtitle ?? \"Enter your PIN to continue\",\n // @ts-ignore\n authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,\n // @ts-ignore\n peerPublicKey: options?.peerPublicKey ?? \"\",\n };\n return module.encrypt(alias, data, o);\n },\n /**\n * Decrypts the given data with the private key for the given alias.\n * @param alias - The alias to use for the key pair.\n * @param data - The data to decrypt in Base64 format.\n * @param options - The options for the operation.\n * @returns The decrypted data.\n */\n decrypt: async (alias: string, data: string, options?: DecryptOptions) => {\n const o = {\n title: options?.promptTitle ?? \"Unlock\",\n subtitle: options?.promptSubtitle ?? \"Enter your PIN to continue\",\n authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,\n algoType: options?.algorithmType ?? EncryptionAlgorithm.RSA_2048_PKCS1,\n // @ts-ignore\n peerPublicKey: options?.peerPublicKey ?? \"\",\n };\n return module.decrypt(alias, data, o);\n },\n};\n"]}
|
package/ios/DeviceCrypto.podspec
CHANGED
package/ios/DeviceCrypto.swift
CHANGED
|
@@ -80,7 +80,7 @@ public class DeviceCryptoModule: Module {
|
|
|
80
80
|
return (item as! SecKey)
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
private func buildECDSA(alias: String, reqAuth: Bool, authMethod: AuthMethod) -> SecKey? {
|
|
83
|
+
private func buildECDSA(alias: String, reqAuth: Bool, authMethod: AuthMethod, reqUnlocked: Bool) -> SecKey? {
|
|
84
84
|
let accessFlags: SecAccessControlCreateFlags
|
|
85
85
|
if reqAuth {
|
|
86
86
|
switch authMethod {
|
|
@@ -93,9 +93,13 @@ public class DeviceCryptoModule: Module {
|
|
|
93
93
|
accessFlags = .privateKeyUsage
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
let lockPolicy = reqUnlocked
|
|
97
|
+
? kSecAttrAccessibleWhenUnlockedThisDeviceOnly
|
|
98
|
+
: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
|
|
99
|
+
|
|
96
100
|
let access = SecAccessControlCreateWithFlags(
|
|
97
101
|
kCFAllocatorDefault,
|
|
98
|
-
|
|
102
|
+
lockPolicy,
|
|
99
103
|
accessFlags,
|
|
100
104
|
nil
|
|
101
105
|
)
|
|
@@ -118,7 +122,7 @@ public class DeviceCryptoModule: Module {
|
|
|
118
122
|
return SecKeyCreateRandomKey(attributes, nil)
|
|
119
123
|
}
|
|
120
124
|
|
|
121
|
-
private func buildRSA(alias: String, keySize: Int, reqAuth: Bool, authMethod: AuthMethod) -> SecKey? {
|
|
125
|
+
private func buildRSA(alias: String, keySize: Int, reqAuth: Bool, authMethod: AuthMethod, reqUnlocked: Bool) -> SecKey? {
|
|
122
126
|
let accessFlags: SecAccessControlCreateFlags
|
|
123
127
|
if reqAuth {
|
|
124
128
|
switch authMethod {
|
|
@@ -131,9 +135,13 @@ public class DeviceCryptoModule: Module {
|
|
|
131
135
|
accessFlags = []
|
|
132
136
|
}
|
|
133
137
|
|
|
138
|
+
let lockPolicy = reqUnlocked
|
|
139
|
+
? kSecAttrAccessibleWhenUnlockedThisDeviceOnly
|
|
140
|
+
: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
|
|
141
|
+
|
|
134
142
|
let access = SecAccessControlCreateWithFlags(
|
|
135
143
|
kCFAllocatorDefault,
|
|
136
|
-
|
|
144
|
+
lockPolicy,
|
|
137
145
|
accessFlags,
|
|
138
146
|
nil
|
|
139
147
|
)
|
|
@@ -155,7 +163,7 @@ public class DeviceCryptoModule: Module {
|
|
|
155
163
|
return SecKeyCreateRandomKey(attributes, nil)
|
|
156
164
|
}
|
|
157
165
|
|
|
158
|
-
private func buildECIES(alias: String, reqAuth: Bool, authMethod: AuthMethod) -> SecKey? {
|
|
166
|
+
private func buildECIES(alias: String, reqAuth: Bool, authMethod: AuthMethod, reqUnlocked: Bool) -> SecKey? {
|
|
159
167
|
let accessFlags: SecAccessControlCreateFlags
|
|
160
168
|
if reqAuth {
|
|
161
169
|
switch authMethod {
|
|
@@ -168,9 +176,13 @@ public class DeviceCryptoModule: Module {
|
|
|
168
176
|
accessFlags = .privateKeyUsage
|
|
169
177
|
}
|
|
170
178
|
|
|
179
|
+
let lockPolicy = reqUnlocked
|
|
180
|
+
? kSecAttrAccessibleWhenUnlockedThisDeviceOnly
|
|
181
|
+
: kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
|
|
182
|
+
|
|
171
183
|
let access = SecAccessControlCreateWithFlags(
|
|
172
184
|
kCFAllocatorDefault,
|
|
173
|
-
|
|
185
|
+
lockPolicy,
|
|
174
186
|
accessFlags,
|
|
175
187
|
nil
|
|
176
188
|
)
|
|
@@ -237,6 +249,7 @@ public class DeviceCryptoModule: Module {
|
|
|
237
249
|
|
|
238
250
|
private func generateKeyPair(alias: String, o: [String: Any]) throws -> String {
|
|
239
251
|
let reqAuth = o["reqAuth"] as! Bool
|
|
252
|
+
let reqUnlocked = o["reqUnlocked"] as! Bool
|
|
240
253
|
let authMethod = AuthMethod(rawValue: o["authMethod"] as! String)
|
|
241
254
|
let algoType = AlgorithmType(rawValue: o["algoType"] as! String)
|
|
242
255
|
|
|
@@ -255,25 +268,25 @@ public class DeviceCryptoModule: Module {
|
|
|
255
268
|
|
|
256
269
|
switch algoType {
|
|
257
270
|
case .ECDSA_SECP256R1_SHA256:
|
|
258
|
-
self.buildECDSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod
|
|
271
|
+
self.buildECDSA(alias: alias, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
259
272
|
case .RSA_2048_PKCS1:
|
|
260
|
-
self.buildRSA(alias: alias, keySize: 2048, reqAuth: reqAuth, authMethod: authMethod
|
|
273
|
+
self.buildRSA(alias: alias, keySize: 2048, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
261
274
|
case .RSA_2048_OAEP_SHA1:
|
|
262
|
-
self.buildRSA(alias: alias, keySize: 2048, reqAuth: reqAuth, authMethod: authMethod
|
|
275
|
+
self.buildRSA(alias: alias, keySize: 2048, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
263
276
|
case .RSA_4096_PKCS1:
|
|
264
|
-
self.buildRSA(alias: alias, keySize: 4096, reqAuth: reqAuth, authMethod: authMethod
|
|
277
|
+
self.buildRSA(alias: alias, keySize: 4096, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
265
278
|
case .RSA_4096_OAEP_SHA1:
|
|
266
|
-
self.buildRSA(alias: alias, keySize: 4096, reqAuth: reqAuth, authMethod: authMethod
|
|
279
|
+
self.buildRSA(alias: alias, keySize: 4096, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
267
280
|
case .ECIES_P256_AES256_GCM:
|
|
268
|
-
self.buildECIES(alias: alias, reqAuth: reqAuth, authMethod: authMethod
|
|
281
|
+
self.buildECIES(alias: alias, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
269
282
|
case .RSA_SHA256:
|
|
270
|
-
self.buildRSA(alias: alias, keySize: 2048, reqAuth: reqAuth, authMethod: authMethod
|
|
283
|
+
self.buildRSA(alias: alias, keySize: 2048, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
271
284
|
case .RSA_SHA256_PSS:
|
|
272
|
-
self.buildRSA(alias: alias, keySize: 2048, reqAuth: reqAuth, authMethod: authMethod
|
|
285
|
+
self.buildRSA(alias: alias, keySize: 2048, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
273
286
|
case .RSA_4096_SHA256:
|
|
274
|
-
self.buildRSA(alias: alias, keySize: 4096, reqAuth: reqAuth, authMethod: authMethod
|
|
287
|
+
self.buildRSA(alias: alias, keySize: 4096, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
275
288
|
case .RSA_4096_SHA256_PSS:
|
|
276
|
-
self.buildRSA(alias: alias, keySize: 4096, reqAuth: reqAuth, authMethod: authMethod
|
|
289
|
+
self.buildRSA(alias: alias, keySize: 4096, reqAuth: reqAuth, authMethod: authMethod!, reqUnlocked: reqUnlocked)
|
|
277
290
|
default:
|
|
278
291
|
throw NSError(
|
|
279
292
|
domain: "DeviceCrypto",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-device-crypto",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Crypto for Expo using device hardware capabilities",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -48,5 +48,10 @@
|
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"expo": "*"
|
|
51
|
+
},
|
|
52
|
+
"peerDependenciesMeta": {
|
|
53
|
+
"expo": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
51
56
|
}
|
|
52
57
|
}
|
|
@@ -74,6 +74,11 @@ export type GenerateKeyPairOptions = {
|
|
|
74
74
|
* @platform android 🤖
|
|
75
75
|
*/
|
|
76
76
|
preferStrongBox?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Whether to require the device to be unlocked to use the key pair.
|
|
79
|
+
* @default true
|
|
80
|
+
*/
|
|
81
|
+
requireUnlockedDevice?: boolean;
|
|
77
82
|
};
|
|
78
83
|
|
|
79
84
|
type BaseAuthOptions = {
|
|
@@ -64,6 +64,7 @@ export default {
|
|
|
64
64
|
reqAuth: options?.requireAuthentication ?? false,
|
|
65
65
|
authMethod: options?.authMethod ?? AuthMethod.PASSCODE_OR_BIOMETRIC,
|
|
66
66
|
preferStrongBox: options?.preferStrongBox ?? false,
|
|
67
|
+
reqUnlocked: options?.requireUnlockedDevice ?? true,
|
|
67
68
|
};
|
|
68
69
|
return module.generateKeyPair(alias, o);
|
|
69
70
|
},
|