Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: [SIW-1310] Generation of cryptographically secure UUIDs #170

Merged
merged 3 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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
Loading