Skip to content

Commit

Permalink
fix(IT Wallet): [SIW-1934] Cleanup the integrityKeyTag if getWalletAt…
Browse files Browse the repository at this point in the history
…testation throws an error (#6569)

## Short description
This PR updates the `WalletInstanceAttestationObtainment` machine step
adding a cleanup function if there is an error.

## List of changes proposed in this pull request
- Added cleanupIntegrityKeyTag if `getWalletAttestation` throws an error

## How to test
Ensure that, when creating a WI, after an error on the
`WalletInstanceAttestationObtainment` step, the `IntegrityKeyTag` has
been correctly deleted, and a new key is generated when retrying to
create a WI.
  • Loading branch information
ale-mazz authored Dec 20, 2024
1 parent a835a70 commit dcde5de
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
3 changes: 3 additions & 0 deletions ts/features/itwallet/common/utils/itwAttestationUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const getIntegrityHardwareKeyTag = async (): Promise<string> =>
/**
* Register a new wallet instance with hardwareKeyTag.
* @param hardwareKeyTag - the hardware key tag of the integrity Context
* @param sessionToken - the session token to use for the API calls
*/
export const registerWalletInstance = async (
hardwareKeyTag: string,
Expand All @@ -42,6 +43,7 @@ export const registerWalletInstance = async (
/**
* Getter for the wallet attestation binded to the wallet instance created with the given hardwareKeyTag.
* @param hardwareKeyTag - the hardware key tag of the wallet instance
* @param sessionToken - the session token to use for the API calls
* @return the wallet attestation and the related key tag
*/
export const getAttestation = async (
Expand Down Expand Up @@ -81,6 +83,7 @@ export const isWalletInstanceAttestationValid = (
* Get the wallet instance status from the Wallet Provider.
* This operation is more lightweight than getting a new attestation to check the status.
* @param hardwareKeyTag The hardware key tag used to create the wallet instance
* @param sessionToken The session token to use for the API calls
*/
export const getWalletInstanceStatus = (
hardwareKeyTag: string,
Expand Down
47 changes: 47 additions & 0 deletions ts/features/itwallet/machine/eid/__tests__/machine.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe("itwEidIssuanceMachine", () => {
const navigateToNfcInstructionsScreen = jest.fn();
const navigateToCieIdLoginScreen = jest.fn();
const storeIntegrityKeyTag = jest.fn();
const cleanupIntegrityKeyTag = jest.fn();
const storeWalletInstanceAttestation = jest.fn();
const storeEidCredential = jest.fn();
const closeIssuance = jest.fn();
Expand Down Expand Up @@ -82,6 +83,7 @@ describe("itwEidIssuanceMachine", () => {
navigateToNfcInstructionsScreen,
navigateToCieIdLoginScreen,
storeIntegrityKeyTag,
cleanupIntegrityKeyTag,
storeWalletInstanceAttestation,
storeEidCredential,
closeIssuance,
Expand Down Expand Up @@ -982,4 +984,49 @@ describe("itwEidIssuanceMachine", () => {

expect(actor.getSnapshot().value).toStrictEqual("Idle");
});

it("should cleanup integrity key tag and fail when obtaining Wallet Instance Attestation fails", async () => {
const actor = createActor(mockedMachine);
actor.start();

await waitFor(() => expect(onInit).toHaveBeenCalledTimes(1));

expect(actor.getSnapshot().value).toStrictEqual("Idle");
expect(actor.getSnapshot().context).toStrictEqual(InitialContext);
expect(actor.getSnapshot().tags).toStrictEqual(new Set());

/**
* Start eID issuance
*/
actor.send({ type: "start" });

expect(actor.getSnapshot().value).toStrictEqual("TosAcceptance");
expect(actor.getSnapshot().tags).toStrictEqual(new Set());
expect(navigateToTosScreen).toHaveBeenCalledTimes(1);

/**
* Accept TOS and request WIA
*/

createWalletInstance.mockImplementation(() =>
Promise.resolve(T_INTEGRITY_KEY)
);
getWalletAttestation.mockImplementation(() => Promise.reject({})); // Simulate failure
isSessionExpired.mockImplementation(() => false); // Session not expired

actor.send({ type: "accept-tos" });

expect(actor.getSnapshot().value).toStrictEqual("WalletInstanceCreation");
expect(actor.getSnapshot().tags).toStrictEqual(new Set([ItwTags.Loading]));

await waitFor(() => expect(createWalletInstance).toHaveBeenCalledTimes(1));
await waitFor(() => expect(getWalletAttestation).toHaveBeenCalledTimes(1));

// Wallet Instance Attestation failure triggers cleanupIntegrityKeyTag
expect(cleanupIntegrityKeyTag).toHaveBeenCalledTimes(1);

// Check that the machine transitions to Failure state
expect(actor.getSnapshot().value).toStrictEqual("Failure");
expect(actor.getSnapshot().tags).toStrictEqual(new Set());
});
});
10 changes: 9 additions & 1 deletion ts/features/itwallet/machine/eid/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { checkCurrentSession } from "../../../../store/actions/authentication";
import { useIOStore } from "../../../../store/hooks";
import { assert } from "../../../../utils/assert";
import { itwCredentialsStore } from "../../credentials/store/actions";
import { itwStoreIntegrityKeyTag } from "../../issuance/store/actions";
import {
itwRemoveIntegrityKeyTag,
itwStoreIntegrityKeyTag
} from "../../issuance/store/actions";
import {
itwLifecycleStateUpdated,
itwLifecycleWalletReset
Expand Down Expand Up @@ -168,6 +171,11 @@ export const createEidIssuanceActionsImplementation = (
store.dispatch(itwStoreIntegrityKeyTag(context.integrityKeyTag));
},

cleanupIntegrityKeyTag: () => {
// Remove the integrity key tag from the store
store.dispatch(itwRemoveIntegrityKeyTag());
},

storeWalletInstanceAttestation: ({
context
}: ActionArgs<Context, EidIssuanceEvents, EidIssuanceEvents>) => {
Expand Down
3 changes: 2 additions & 1 deletion ts/features/itwallet/machine/eid/machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const itwEidIssuanceMachine = setup({
navigateToNfcInstructionsScreen: notImplemented,
navigateToWalletRevocationScreen: notImplemented,
storeIntegrityKeyTag: notImplemented,
cleanupIntegrityKeyTag: notImplemented,
storeWalletInstanceAttestation: notImplemented,
storeEidCredential: notImplemented,
closeIssuance: notImplemented,
Expand Down Expand Up @@ -225,7 +226,7 @@ export const itwEidIssuanceMachine = setup({
target: "#itwEidIssuanceMachine.TosAcceptance"
},
{
actions: "setFailure",
actions: ["setFailure", "cleanupIntegrityKeyTag"],
target: "#itwEidIssuanceMachine.Failure"
}
]
Expand Down

0 comments on commit dcde5de

Please sign in to comment.