Skip to content

Commit

Permalink
chore: [SIW-1310] Generation of cryptographically secure UUIDs (#170)
Browse files Browse the repository at this point in the history
  • Loading branch information
RiccardoMolinari95 authored Jan 27, 2025
1 parent 3d801ea commit 56ad858
Show file tree
Hide file tree
Showing 19 changed files with 74 additions and 39 deletions.
1 change: 1 addition & 0 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'react-native-get-random-values';
import { AppRegistry } from "react-native";
import App from "./src/App";
import { name as appName } from "./app.json";
Expand Down
6 changes: 6 additions & 0 deletions example/ios/Podfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"react": "18.2.0",
"react-native": "0.72.14",
"react-native-gesture-handler": "^2.18.1",
"react-native-get-random-values": "^1.11.0",
"react-native-haptic-feedback": "^2.3.1",
"react-native-qrcode-svg": "^6.3.12",
"react-native-reanimated": "^3.15.1",
Expand Down
4 changes: 2 additions & 2 deletions example/src/thunks/pid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
Credential,
WalletInstanceAttestation,
} from "@pagopa/io-react-native-wallet";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import {
selectAttestation,
shouldRequestAttestationSelector,
Expand Down Expand Up @@ -194,7 +194,7 @@ export const continuePidFlowThunk = createAppAsyncThunk<
const wiaCryptoContext = createCryptoContextFor(WIA_KEYTAG);

// Create credential crypto context
const credentialKeyTag = uuid.v4().toString();
const credentialKeyTag = uuidv4().toString();
await generate(credentialKeyTag);
const credentialCryptoContext = createCryptoContextFor(credentialKeyTag);

Expand Down
6 changes: 3 additions & 3 deletions example/src/utils/credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
Credential,
createCryptoContextFor,
} from "@pagopa/io-react-native-wallet";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import { generate } from "@pagopa/io-react-native-crypto";
import appFetch from "../utils/fetch";
import { DPOP_KEYTAG, regenerateCryptoKey } from "../utils/crypto";
Expand Down Expand Up @@ -43,7 +43,7 @@ export const getPidCieID = async ({
* Create credential crypto context for the PID
* WARNING: The eID keytag must be persisted and later used when requesting a credential which requires a eID presentation
*/
const credentialKeyTag = uuid.v4().toString();
const credentialKeyTag = uuidv4().toString();
await generate(credentialKeyTag);
const credentialCryptoContext = createCryptoContextFor(credentialKeyTag);

Expand Down Expand Up @@ -172,7 +172,7 @@ export const getCredential = async ({
pidCryptoContext: CryptoContext;
}): Promise<CredentialResult> => {
// Create credential crypto context
const credentialKeyTag = uuid.v4().toString();
const credentialKeyTag = uuidv4().toString();
await generate(credentialKeyTag);
const credentialCryptoContext = createCryptoContextFor(credentialKeyTag);

Expand Down
4 changes: 2 additions & 2 deletions example/src/utils/integrity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
requestIntegrityToken,
} from "@pagopa/io-react-native-integrity";
import { Platform } from "react-native";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import { addPadding, removePadding } from "@pagopa/io-react-native-jwt";
import { sha256 } from "js-sha256";
import type { IntegrityContext } from "@pagopa/io-react-native-wallet";
Expand Down Expand Up @@ -63,7 +63,7 @@ const generateIntegrityHardwareKeyTag = () =>
return removePadding(key);
},
android: async () => {
const keyTag = uuid.v4().toString();
const keyTag = uuidv4().toString();
await generate(keyTag);
return keyTag;
},
Expand Down
12 changes: 12 additions & 0 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3442,6 +3442,11 @@ execa@^5.0.0:
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"

fast-base64-decode@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz#b434a0dd7d92b12b43f26819300d2dafb83ee418"
integrity sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==

fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
Expand Down Expand Up @@ -5437,6 +5442,13 @@ react-native-gesture-handler@^2.12.0, react-native-gesture-handler@^2.18.1:
invariant "^2.2.4"
prop-types "^15.7.2"

react-native-get-random-values@^1.11.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/react-native-get-random-values/-/react-native-get-random-values-1.11.0.tgz#1ca70d1271f4b08af92958803b89dccbda78728d"
integrity sha512-4BTbDbRmS7iPdhYLRcz3PGFIpFJBwNZg9g42iwa2P6FOv9vZj/xJc678RZXnLNZzd0qd7Q3CCF6Yd+CU2eoXKQ==
dependencies:
fast-base64-decode "^1.0.0"

react-native-haptic-feedback@^2.0.2, react-native-haptic-feedback@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/react-native-haptic-feedback/-/react-native-haptic-feedback-2.3.1.tgz#2ef4ac7d4f63ac06bd64b659f509362f127b16e5"
Expand Down
9 changes: 9 additions & 0 deletions jestSetup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Set up of the testing environment
*/

jest.mock("uuid", () => {
return {
v4: jest.fn(() => "mocked-uuid"),
};
});
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@
"modulePathIgnorePatterns": [
"<rootDir>/example/node_modules",
"<rootDir>/lib/"
],
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?@react-native|react-native|uuid)"
],
"setupFiles": [
"<rootDir>/jestSetup.js"
]
},
"react-native-builder-bob": {
Expand All @@ -111,7 +117,7 @@
"js-sha256": "^0.9.0",
"parse-url": "^9.2.0",
"react-native-url-polyfill": "^2.0.0",
"react-native-uuid": "^2.0.1",
"uuid": "^11.0.3",
"zod": "^3.21.4"
}
}
}
10 changes: 5 additions & 5 deletions src/credential/issuance/04-complete-user-authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
type CryptoContext,
} from "@pagopa/io-react-native-jwt";
import { RequestObject } from "../presentation/types";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import { ResponseUriResultShape } from "./types";
import { getJwtFromFormPost } from "../../utils/decoder";
import { AuthorizationError, AuthorizationIdpError } from "./errors";
Expand Down Expand Up @@ -169,7 +169,7 @@ export const completeUserAuthorizationWithFormPostJwtMode: CompleteUserAuthoriza
})
.setPayload({
vp: walletInstanceAttestation,
jti: uuid.v4().toString(),
jti: uuidv4().toString(),
nonce: requestObject.nonce,
})
.setIssuedAt()
Expand All @@ -184,7 +184,7 @@ export const completeUserAuthorizationWithFormPostJwtMode: CompleteUserAuthoriza
})
.setPayload({
vp: pid,
jti: uuid.v4().toString(),
jti: uuidv4().toString(),
nonce: requestObject.nonce,
})
.setIssuedAt()
Expand All @@ -196,8 +196,8 @@ export const completeUserAuthorizationWithFormPostJwtMode: CompleteUserAuthoriza
* is cointaned in the `vp` property of the signed jwt token payload
*/
const presentationSubmission = {
definition_id: `${uuid.v4()}`,
id: `${uuid.v4()}`,
definition_id: `${uuidv4()}`,
id: `${uuidv4()}`,
descriptor_map: [
{
id: "PersonIdentificationData",
Expand Down
6 changes: 3 additions & 3 deletions src/credential/issuance/05-authorize-access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { hasStatusOrThrow, type Out } from "../../utils/misc";
import type { EvaluateIssuerTrust } from "./02-evaluate-issuer-trust";
import type { StartUserAuthorization } from "./03-start-user-authorization";
import { createDPopToken } from "../../utils/dpop";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import { createPopToken } from "../../utils/pop";
import * as WalletInstanceAttestation from "../../wallet-instance-attestation";
import type { CryptoContext } from "@pagopa/io-react-native-jwt";
Expand Down Expand Up @@ -71,14 +71,14 @@ export const authorizeAccess: AuthorizeAccess = async (
{
htm: "POST",
htu: tokenUrl,
jti: `${uuid.v4()}`,
jti: `${uuidv4()}`,
},
dPopCryptoContext
);

const signedWiaPoP = await createPopToken(
{
jti: `${uuid.v4()}`,
jti: `${uuidv4()}`,
aud,
iss,
},
Expand Down
4 changes: 2 additions & 2 deletions src/credential/issuance/06-obtain-credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from "../../utils/errors";
import { CredentialResponse } from "./types";
import { createDPopToken } from "../../utils/dpop";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";

export type ObtainCredential = (
issuerConf: Out<EvaluateIssuerTrust>["issuerConf"],
Expand Down Expand Up @@ -127,7 +127,7 @@ export const obtainCredential: ObtainCredential = async (
{
htm: "POST",
htu: credentialUrl,
jti: `${uuid.v4()}`,
jti: `${uuidv4()}`,
ath: await sha256ToBase64(accessToken.access_token),
},
dPopCryptoContext
Expand Down
4 changes: 2 additions & 2 deletions src/credential/issuance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ const eid = {
const eidCryptoContext = createCryptoContextFor(eid.keyTag);

// Create credential crypto context
const credentialKeyTag = uuid.v4().toString();
const credentialKeyTag = uuidv4().toString();
await generate(credentialKeyTag); // Let's assume this function generates a new hardware-backed key pair
const credentialCryptoContext = createCryptoContextFor(credentialKeyTag);

Expand Down Expand Up @@ -244,7 +244,7 @@ const authorizationContext = idpHint.includes("servizicie")
* Create credential crypto context for the PID
* WARNING: The eID keytag must be persisted and later used when requesting a credential which requires a eID presentation
*/
const credentialKeyTag = uuid.v4().toString();
const credentialKeyTag = uuidv4().toString();
await generate(credentialKeyTag);
const credentialCryptoContext = createCryptoContextFor(credentialKeyTag);

Expand Down
4 changes: 2 additions & 2 deletions src/credential/presentation/03-get-request-object.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import {
decode as decodeJwt,
sha256ToBase64,
Expand Down Expand Up @@ -41,7 +41,7 @@ export const getRequestObject: GetRequestObject = async (
) => {
const signedWalletInstanceDPoP = await createDPopToken(
{
jti: `${uuid.v4()}`,
jti: `${uuidv4()}`,
htm: "GET",
htu: requestUri,
ath: await sha256ToBase64(walletInstanceAttestation),
Expand Down
8 changes: 4 additions & 4 deletions src/credential/presentation/04-send-authorization-response.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EncryptJwe, SignJWT } from "@pagopa/io-react-native-jwt";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import * as WalletInstanceAttestation from "../../wallet-instance-attestation";
import type { JWK } from "@pagopa/io-react-native-jwt/lib/typescript/types";
import { NoSuitableKeysFoundInEntityConfiguration } from "./errors";
Expand Down Expand Up @@ -79,7 +79,7 @@ const prepareVpToken = async (
})
.setPayload({
vp: vp,
jti: `${uuid.v4()}`,
jti: `${uuidv4()}`,
iss,
nonce: requestObject.nonce,
})
Expand All @@ -90,8 +90,8 @@ const prepareVpToken = async (

const vc_scope = requestObject.scope;
const presentation_submission = {
definition_id: `${uuid.v4()}`,
id: `${uuid.v4()}`,
definition_id: `${uuidv4()}`,
id: `${uuidv4()}`,
descriptor_map: paths.map((p) => ({
id: vc_scope,
path: `$.vp_token.${p.path}`,
Expand Down
4 changes: 2 additions & 2 deletions src/credential/status/02-status-attestation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from "../../utils/misc";
import type { EvaluateIssuerTrust, ObtainCredential } from "../issuance";
import { type CryptoContext, SignJWT } from "@pagopa/io-react-native-jwt";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import { StatusAttestationResponse } from "./types";
import {
IssuerResponseError,
Expand Down Expand Up @@ -46,7 +46,7 @@ export const statusAttestation: StatusAttestation = async (
const credentialPop = await new SignJWT(credentialCryptoContext)
.setPayload({
aud: statusAttUrl,
jti: uuid.v4().toString(),
jti: uuidv4().toString(),
credential_hash: credentialHash,
credential_hash_alg: "S256",
})
Expand Down
4 changes: 2 additions & 2 deletions src/utils/crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
generate,
deleteKey,
} from "@pagopa/io-react-native-crypto";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import { thumbprint, type CryptoContext } from "@pagopa/io-react-native-jwt";
import { fixBase64EncodingOnKey } from "./jwk";

Expand Down Expand Up @@ -58,7 +58,7 @@ export const withEphemeralKey = async <R>(
fn: (ephemeralContext: CryptoContext) => Promise<R>
): Promise<R> => {
// Use an ephemeral key to be destroyed after use
const keytag = `ephemeral-${uuid.v4()}`;
const keytag = `ephemeral-${uuidv4()}`;
await generate(keytag);
const ephemeralContext = createCryptoContextFor(keytag);
return fn(ephemeralContext).finally(() => deleteKey(keytag));
Expand Down
6 changes: 3 additions & 3 deletions src/utils/par.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
type CryptoContext,
SignJWT,
} from "@pagopa/io-react-native-jwt";
import uuid from "react-native-uuid";
import { v4 as uuidv4 } from "uuid";
import * as z from "zod";
import * as WalletInstanceAttestation from "../wallet-instance-attestation";
import { generateRandomAlphaNumericString, hasStatusOrThrow } from "./misc";
Expand Down Expand Up @@ -51,7 +51,7 @@ export const makeParRequest =

const signedWiaPoP = await createPopToken(
{
jti: `${uuid.v4()}`,
jti: `${uuidv4()}`,
aud,
iss,
},
Expand All @@ -74,7 +74,7 @@ export const makeParRequest =
kid: wiaPublicKey.kid,
})
.setPayload({
jti: `${uuid.v4()}`,
jti: `${uuidv4()}`,
aud,
response_type: "code",
response_mode: responseMode,
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7408,11 +7408,6 @@ react-native-url-polyfill@^2.0.0:
dependencies:
whatwg-url-without-unicode "8.0.0-3"

react-native-uuid@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/react-native-uuid/-/react-native-uuid-2.0.1.tgz#ed4e2dfb1683eddb66967eb5dca140dfe1abddb9"
integrity sha512-cptnoIbL53GTCrWlb/+jrDC6tvb7ypIyzbXNJcpR3Vab0mkeaaVd5qnB3f0whXYzS+SMoSQLcUUB0gEWqkPC0g==

[email protected]:
version "0.72.14"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.72.14.tgz#d69c7bec66716946ea96613813618ba10403f942"
Expand Down Expand Up @@ -8707,6 +8702,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==

uuid@^11.0.3:
version "11.0.3"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.0.3.tgz#248451cac9d1a4a4128033e765d137e2b2c49a3d"
integrity sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==

v8-to-istanbul@^9.0.1:
version "9.1.0"
resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265"
Expand Down

0 comments on commit 56ad858

Please sign in to comment.