@oxy.so/core 7.31.0 → 7.33.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/dist/cjs/api/identity.js +155 -24
- package/dist/cjs/crypto/identityMarker.js +15 -0
- package/dist/cjs/crypto/index.js +11 -2
- package/dist/cjs/crypto/keyManager.js +111 -16
- package/dist/cjs/crypto/keychainGroupMigration.js +327 -160
- package/dist/cjs/crypto/organizationKeys.js +33 -5
- package/dist/cjs/crypto/retiredKeys.js +315 -64
- package/dist/cjs/utils/keychainAccessGroups.js +111 -25
- package/dist/esm/api/identity.js +155 -24
- package/dist/esm/crypto/identityMarker.js +14 -0
- package/dist/esm/crypto/index.js +3 -3
- package/dist/esm/crypto/keyManager.js +113 -18
- package/dist/esm/crypto/keychainGroupMigration.js +327 -162
- package/dist/esm/crypto/organizationKeys.js +34 -6
- package/dist/esm/crypto/retiredKeys.js +306 -63
- package/dist/esm/utils/keychainAccessGroups.js +107 -24
- package/dist/types/api/identity.d.ts +36 -0
- package/dist/types/crypto/identityMarker.d.ts +8 -0
- package/dist/types/crypto/index.d.ts +3 -3
- package/dist/types/crypto/keyManager.d.ts +45 -1
- package/dist/types/crypto/keychainGroupMigration.d.ts +28 -6
- package/dist/types/crypto/organizationKeys.d.ts +4 -2
- package/dist/types/crypto/retiredKeys.d.ts +108 -17
- package/dist/types/utils/keychainAccessGroups.d.ts +41 -11
- package/package.json +1 -1
- package/src/api/identity.ts +198 -41
- package/src/crypto/identityMarker.ts +15 -0
- package/src/crypto/index.ts +12 -1
- package/src/crypto/keyManager.ts +127 -26
- package/src/crypto/keychainGroupMigration.ts +390 -185
- package/src/crypto/organizationKeys.ts +38 -6
- package/src/crypto/retiredKeys.ts +369 -65
- package/src/utils/keychainAccessGroups.ts +121 -24
|
@@ -47,7 +47,8 @@ import {
|
|
|
47
47
|
} from '../utils/keychainAccessGroups';
|
|
48
48
|
import { isAndroid, isIOS, isWeb } from '../utils/platform';
|
|
49
49
|
import { registeredIdentitySignerStore } from './identitySigner';
|
|
50
|
-
import {
|
|
50
|
+
import { prepareKeychainAccess } from './keychainGroupMigration';
|
|
51
|
+
import { retireIdentityKey } from './retiredKeys';
|
|
51
52
|
import {
|
|
52
53
|
ORGANIZATION_ANDROID_KEYCHAIN_SERVICE as ANDROID_KEYCHAIN_SERVICE,
|
|
53
54
|
ORGANIZATION_INDEX_KEYCHAIN_SERVICE as INDEX_KEYCHAIN_SERVICE,
|
|
@@ -158,9 +159,7 @@ export async function organizationKeyFromPhrase(phrase: string): Promise<Organiz
|
|
|
158
159
|
async function secureStore(item: KeychainItemClass): Promise<ExpoSecureStoreLike> {
|
|
159
160
|
const raw = await loadSecureStore();
|
|
160
161
|
const access = await resolveKeychainAccess();
|
|
161
|
-
|
|
162
|
-
await ensureKeychainGroupsMigrated();
|
|
163
|
-
}
|
|
162
|
+
await prepareKeychainAccess(access);
|
|
164
163
|
return groupedKeychainStore(raw, access, item);
|
|
165
164
|
}
|
|
166
165
|
|
|
@@ -252,8 +251,10 @@ async function readLocalPair(accountId: string): Promise<OrganizationKeyPair | n
|
|
|
252
251
|
* it; on iOS only Commons holds the groups it writes (any other app throws).
|
|
253
252
|
*
|
|
254
253
|
* Refuses a pair whose public key does not derive from its private key, and a
|
|
255
|
-
* phrase that does not derive the pair.
|
|
256
|
-
* the organization
|
|
254
|
+
* phrase that does not derive the pair. A DIFFERENT key this device already
|
|
255
|
+
* held for the organization is first kept in the organization's retired ring
|
|
256
|
+
* (ADR 0061 D7 as amended; R4-12): coins under it still need it. When that
|
|
257
|
+
* cannot be confirmed nothing is overwritten and this throws.
|
|
257
258
|
*/
|
|
258
259
|
export async function storeOrganizationKey(
|
|
259
260
|
accountId: string,
|
|
@@ -280,6 +281,19 @@ export async function storeOrganizationKey(
|
|
|
280
281
|
);
|
|
281
282
|
}
|
|
282
283
|
const store = await pairStore();
|
|
284
|
+
const previous = await heldPrivateKey(store, accountId);
|
|
285
|
+
if (previous) {
|
|
286
|
+
const previousPublic = deriveSecp256k1PublicKey(previous);
|
|
287
|
+
if (previousPublic !== publicKey) {
|
|
288
|
+
try {
|
|
289
|
+
await retireIdentityKey({ privateKey: previous, publicKey: previousPublic }, { accountId });
|
|
290
|
+
} catch (error) {
|
|
291
|
+
throw new Error(
|
|
292
|
+
`organization key: the key this device held could not be kept as a previous key, so it was not replaced (${error instanceof Error ? error.message : 'unknown'})`,
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
283
297
|
await store.setItemAsync(privateKeyName(accountId), privateKey, pairOptions(store, true));
|
|
284
298
|
await store.setItemAsync(publicKeyName(accountId), publicKey, pairOptions(store, false));
|
|
285
299
|
if (
|
|
@@ -362,6 +376,24 @@ export async function listOrganizationKeys(): Promise<string[]> {
|
|
|
362
376
|
return readIndex(await indexStore());
|
|
363
377
|
}
|
|
364
378
|
|
|
379
|
+
/**
|
|
380
|
+
* The private key this device holds for `accountId`, whatever its public half
|
|
381
|
+
* says (an unhealthy pair is still a key coins may sit under): the slot, then
|
|
382
|
+
* on Android the signer store's copy. `null` when there is none.
|
|
383
|
+
*/
|
|
384
|
+
async function heldPrivateKey(
|
|
385
|
+
store: ExpoSecureStoreLike,
|
|
386
|
+
accountId: string,
|
|
387
|
+
): Promise<string | null> {
|
|
388
|
+
const local = await store.getItemAsync(privateKeyName(accountId), pairOptions(store, false));
|
|
389
|
+
if (local && isValidSecp256k1PrivateKey(local)) return normalizeSecp256k1PrivateKey(local);
|
|
390
|
+
const signer = isAndroid() ? registeredIdentitySignerStore() : null;
|
|
391
|
+
const mirrored = (await signer?.readOrganization?.(accountId)) ?? null;
|
|
392
|
+
return mirrored && isValidSecp256k1PrivateKey(mirrored.privateKey)
|
|
393
|
+
? normalizeSecp256k1PrivateKey(mirrored.privateKey)
|
|
394
|
+
: null;
|
|
395
|
+
}
|
|
396
|
+
|
|
365
397
|
/** Forget an organization key on this device: its pair, its phrase, its signer copy and its index entry. */
|
|
366
398
|
export async function deleteOrganizationKey(accountId: string): Promise<void> {
|
|
367
399
|
assertAccountId(accountId);
|