Skip to content

iOS: test the locked-keychain path in RootKeyStore #40

@gmaclennan

Description

@gmaclennan

Context

PR #36 added RootKeyStore.swift which throws RootKeyError.interactionNotAllowed when SecItemCopyMatching returns errSecInteractionNotAllowed — the case where the device has been booted but never unlocked since.

The XCTest suite added in PR #36 covers round-trip and wrong-length, but not the locked-keychain path. That branch is reachable in production (cold reboot, app launches via background trigger before user has unlocked once) and has its own native ERROR transition (phase: "rootkey"), so it's worth pinning down with a test.

Why deferred

Simulating errSecInteractionNotAllowed in XCTest is fiddly:

  • The simulator's keychain is always "unlocked" once the simulator has booted. There's no public API to lock it.
  • One workaround is creating an item with kSecAttrAccessible = kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly on a simulator without a passcode, but the resulting error is errSecAuthFailed, not errSecInteractionNotAllowed.
  • The cleanest approach is probably a small protocol-based mock injected at RootKeyStore construction (e.g. a KeychainAccessor typealias), with the production path going through the real SecItem* functions and the test using a fake that returns the desired OSStatus.

That refactor is a couple of hundred lines and changes the public API of RootKeyStore. PR #36 review explicitly deferred it.

Acceptance

  • RootKeyStore accepts a keychain-accessor seam (protocol or closure) for tests.
  • XCTest covers: load returns nil + locked → throws .interactionNotAllowed.
  • XCTest covers: store while locked → throws .interactionNotAllowed.
  • Production callers continue to use the real Keychain by default (no behaviour change).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions