@pagopa/io-react-native-wallet 2.0.0-next.4 → 2.0.0-next.6
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/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js +3 -3
- package/lib/commonjs/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/commonjs/credential/status/{02-status-attestation.js → 02-status-assertion.js} +28 -22
- package/lib/commonjs/credential/status/02-status-assertion.js.map +1 -0
- package/lib/commonjs/credential/status/03-verify-and-parse-status-assertion.js +85 -0
- package/lib/commonjs/credential/status/03-verify-and-parse-status-assertion.js.map +1 -0
- package/lib/commonjs/credential/status/README.md +22 -20
- package/lib/commonjs/credential/status/index.js +6 -6
- package/lib/commonjs/credential/status/index.js.map +1 -1
- package/lib/commonjs/credential/status/types.js +48 -15
- package/lib/commonjs/credential/status/types.js.map +1 -1
- package/lib/commonjs/trust/types.js +2 -1
- package/lib/commonjs/trust/types.js.map +1 -1
- package/lib/commonjs/utils/credentials.js +33 -0
- package/lib/commonjs/utils/credentials.js.map +1 -0
- package/lib/commonjs/utils/crypto.js +1 -7
- package/lib/commonjs/utils/crypto.js.map +1 -1
- package/lib/commonjs/utils/jwk.js +12 -0
- package/lib/commonjs/utils/jwk.js.map +1 -1
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js +4 -4
- package/lib/module/credential/issuance/07-verify-and-parse-credential.js.map +1 -1
- package/lib/module/credential/status/{02-status-attestation.js → 02-status-assertion.js} +28 -22
- package/lib/module/credential/status/02-status-assertion.js.map +1 -0
- package/lib/module/credential/status/03-verify-and-parse-status-assertion.js +78 -0
- package/lib/module/credential/status/03-verify-and-parse-status-assertion.js.map +1 -0
- package/lib/module/credential/status/README.md +22 -20
- package/lib/module/credential/status/index.js +3 -3
- package/lib/module/credential/status/index.js.map +1 -1
- package/lib/module/credential/status/types.js +43 -12
- package/lib/module/credential/status/types.js.map +1 -1
- package/lib/module/trust/types.js +2 -1
- package/lib/module/trust/types.js.map +1 -1
- package/lib/module/utils/credentials.js +26 -0
- package/lib/module/utils/credentials.js.map +1 -0
- package/lib/module/utils/crypto.js +2 -8
- package/lib/module/utils/crypto.js.map +1 -1
- package/lib/module/utils/jwk.js +11 -1
- package/lib/module/utils/jwk.js.map +1 -1
- package/lib/typescript/credential/issuance/07-verify-and-parse-credential.d.ts.map +1 -1
- package/lib/typescript/credential/status/02-status-assertion.d.ts +23 -0
- package/lib/typescript/credential/status/02-status-assertion.d.ts.map +1 -0
- package/lib/typescript/credential/status/03-verify-and-parse-status-assertion.d.ts +21 -0
- package/lib/typescript/credential/status/03-verify-and-parse-status-assertion.d.ts.map +1 -0
- package/lib/typescript/credential/status/index.d.ts +4 -4
- package/lib/typescript/credential/status/index.d.ts.map +1 -1
- package/lib/typescript/credential/status/types.d.ts +495 -18
- package/lib/typescript/credential/status/types.d.ts.map +1 -1
- package/lib/typescript/trust/build-chain.d.ts +2 -2
- package/lib/typescript/trust/types.d.ts +26 -26
- package/lib/typescript/utils/credentials.d.ts +11 -0
- package/lib/typescript/utils/credentials.d.ts.map +1 -0
- package/lib/typescript/utils/crypto.d.ts.map +1 -1
- package/lib/typescript/utils/jwk.d.ts +7 -0
- package/lib/typescript/utils/jwk.d.ts.map +1 -1
- package/package.json +6 -8
- package/src/credential/issuance/07-verify-and-parse-credential.ts +4 -6
- package/src/credential/status/{02-status-attestation.ts → 02-status-assertion.ts} +37 -28
- package/src/credential/status/03-verify-and-parse-status-assertion.ts +109 -0
- package/src/credential/status/README.md +22 -20
- package/src/credential/status/index.ts +7 -14
- package/src/credential/status/types.ts +62 -15
- package/src/trust/types.ts +1 -1
- package/src/utils/credentials.ts +29 -0
- package/src/utils/crypto.ts +12 -20
- package/src/utils/jwk.ts +15 -1
- package/lib/commonjs/credential/status/02-status-attestation.js.map +0 -1
- package/lib/commonjs/credential/status/03-verify-and-parse-status-attestation.js +0 -55
- package/lib/commonjs/credential/status/03-verify-and-parse-status-attestation.js.map +0 -1
- package/lib/module/credential/status/02-status-attestation.js.map +0 -1
- package/lib/module/credential/status/03-verify-and-parse-status-attestation.js +0 -49
- package/lib/module/credential/status/03-verify-and-parse-status-attestation.js.map +0 -1
- package/lib/typescript/credential/status/02-status-attestation.d.ts +0 -19
- package/lib/typescript/credential/status/02-status-attestation.d.ts.map +0 -1
- package/lib/typescript/credential/status/03-verify-and-parse-status-attestation.d.ts +0 -24
- package/lib/typescript/credential/status/03-verify-and-parse-status-attestation.d.ts.map +0 -1
- package/src/credential/status/03-verify-and-parse-status-attestation.ts +0 -70
@@ -1,22 +1,15 @@
|
|
1
1
|
import { type StartFlow } from "./01-start-flow";
|
2
|
-
import {
|
3
|
-
statusAttestation,
|
4
|
-
type StatusAttestation,
|
5
|
-
} from "./02-status-attestation";
|
2
|
+
import { statusAssertion, type StatusAssertion } from "./02-status-assertion";
|
6
3
|
import { evaluateIssuerTrust, type EvaluateIssuerTrust } from "../issuance";
|
7
4
|
import {
|
8
|
-
|
9
|
-
type
|
10
|
-
} from "./03-verify-and-parse-status-
|
5
|
+
verifyAndParseStatusAssertion,
|
6
|
+
type VerifyAndParseStatusAssertion,
|
7
|
+
} from "./03-verify-and-parse-status-assertion";
|
11
8
|
|
12
|
-
export {
|
13
|
-
evaluateIssuerTrust,
|
14
|
-
statusAttestation,
|
15
|
-
verifyAndParseStatusAttestation,
|
16
|
-
};
|
9
|
+
export { evaluateIssuerTrust, statusAssertion, verifyAndParseStatusAssertion };
|
17
10
|
export type {
|
18
11
|
StartFlow,
|
19
12
|
EvaluateIssuerTrust,
|
20
|
-
|
21
|
-
|
13
|
+
StatusAssertion,
|
14
|
+
VerifyAndParseStatusAssertion,
|
22
15
|
};
|
@@ -3,35 +3,38 @@ import { JWK } from "../../utils/jwk";
|
|
3
3
|
import * as z from "zod";
|
4
4
|
|
5
5
|
/**
|
6
|
-
* Shape from parsing a status
|
6
|
+
* Shape from parsing a status assertion response in case of 201.
|
7
7
|
*/
|
8
|
-
export const
|
9
|
-
|
8
|
+
export const StatusAssertionResponse = z.object({
|
9
|
+
status_assertion_responses: z.array(z.string()),
|
10
10
|
});
|
11
11
|
|
12
12
|
/**
|
13
|
-
* Type from parsing a status
|
14
|
-
* Inferred from {@link
|
13
|
+
* Type from parsing a status assertion response in case of 201.
|
14
|
+
* Inferred from {@link StatusAssertionResponse}.
|
15
15
|
*/
|
16
|
-
export type
|
17
|
-
typeof StatusAttestationResponse
|
18
|
-
>;
|
16
|
+
export type StatusAssertionResponse = z.infer<typeof StatusAssertionResponse>;
|
19
17
|
|
20
|
-
|
21
|
-
* Type for a parsed status attestation.
|
22
|
-
*/
|
23
|
-
export type ParsedStatusAttestation = z.infer<typeof ParsedStatusAttestation>;
|
18
|
+
export type ParsedStatusAssertion = z.infer<typeof ParsedStatusAssertion>;
|
24
19
|
|
25
20
|
/**
|
26
|
-
* Shape for parsing a status
|
21
|
+
* Shape for parsing a successful status assertion in a JWT.
|
27
22
|
*/
|
28
|
-
export const
|
23
|
+
export const ParsedStatusAssertion = z.object({
|
29
24
|
header: z.object({
|
30
|
-
typ: z.literal("status-
|
25
|
+
typ: z.literal("status-assertion+jwt"),
|
31
26
|
alg: z.string(),
|
32
27
|
kid: z.string().optional(),
|
33
28
|
}),
|
34
29
|
payload: z.object({
|
30
|
+
iss: z.string(),
|
31
|
+
credential_status_type: z.string(),
|
32
|
+
credential_status_detail: z
|
33
|
+
.object({
|
34
|
+
state: z.string(),
|
35
|
+
description: z.string(),
|
36
|
+
})
|
37
|
+
.optional(),
|
35
38
|
credential_hash_alg: z.string(),
|
36
39
|
credential_hash: z.string(),
|
37
40
|
cnf: z.object({
|
@@ -41,3 +44,47 @@ export const ParsedStatusAttestation = z.object({
|
|
41
44
|
iat: UnixTime,
|
42
45
|
}),
|
43
46
|
});
|
47
|
+
|
48
|
+
export type ParsedStatusAssertionError = z.infer<
|
49
|
+
typeof ParsedStatusAssertionError
|
50
|
+
>;
|
51
|
+
|
52
|
+
/**
|
53
|
+
* The JWT that contains the errors occurred for the status assertion request.
|
54
|
+
* @see https://italia.github.io/eid-wallet-it-docs/versione-corrente/en/credential-revocation.html#http-status-assertion-response
|
55
|
+
*/
|
56
|
+
export const ParsedStatusAssertionError = z.object({
|
57
|
+
header: z.object({
|
58
|
+
typ: z.literal("status-assertion-error+jwt"),
|
59
|
+
alg: z.string(),
|
60
|
+
kid: z.string().optional(),
|
61
|
+
}),
|
62
|
+
payload: z.object({
|
63
|
+
credential_hash_alg: z.string(),
|
64
|
+
credential_hash: z.string(),
|
65
|
+
error: z.string(),
|
66
|
+
error_description: z.string(),
|
67
|
+
}),
|
68
|
+
});
|
69
|
+
|
70
|
+
/**
|
71
|
+
* The status assertion response that might include either a successful assertion or an error
|
72
|
+
*/
|
73
|
+
export type ParsedStatusAssertionResponse = z.infer<
|
74
|
+
typeof ParsedStatusAssertionResponse
|
75
|
+
>;
|
76
|
+
export const ParsedStatusAssertionResponse = z.union([
|
77
|
+
ParsedStatusAssertion,
|
78
|
+
ParsedStatusAssertionError,
|
79
|
+
]);
|
80
|
+
|
81
|
+
export enum StatusType {
|
82
|
+
VALID = "0x00",
|
83
|
+
INVALID = "0x01",
|
84
|
+
SUSPENDED = "0x02",
|
85
|
+
}
|
86
|
+
|
87
|
+
export type InvalidStatusErrorReason = {
|
88
|
+
error: string;
|
89
|
+
error_description: string;
|
90
|
+
};
|
package/src/trust/types.ts
CHANGED
@@ -38,7 +38,7 @@ const CredentialIssuerDisplayMetadata = z.object({
|
|
38
38
|
|
39
39
|
type ClaimsMetadata = z.infer<typeof ClaimsMetadata>;
|
40
40
|
const ClaimsMetadata = z.object({
|
41
|
-
path: z.array(z.string()),
|
41
|
+
path: z.array(z.union([z.string(), z.number(), z.null()])), // https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0-15.html#name-claims-path-pointer
|
42
42
|
display: z.array(CredentialDisplayMetadata),
|
43
43
|
});
|
44
44
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { decode } from "../sd-jwt";
|
2
|
+
import { thumbprint } from "@pagopa/io-react-native-jwt";
|
3
|
+
import type { Out } from "./misc";
|
4
|
+
import type { ObtainCredential } from "../credential/issuance";
|
5
|
+
import type { JWK } from "./jwk";
|
6
|
+
import { IoWalletError } from "./errors";
|
7
|
+
|
8
|
+
const SD_JWT = ["vc+sd-jwt", "dc+sd-jwt"];
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Extracts a JWK from a credential.
|
12
|
+
* @param credential - The credential string, which can be in SD-JWT or CBOR format.
|
13
|
+
* @param format - The format of the credential
|
14
|
+
* @return A Promise that resolves to a JWK object if the credential is in SD-JWT format and contains a JWK, or undefined otherwise.
|
15
|
+
*/
|
16
|
+
export const extractJwkFromCredential = async (
|
17
|
+
credential: Out<ObtainCredential>["credential"],
|
18
|
+
format: Out<ObtainCredential>["format"]
|
19
|
+
): Promise<JWK> => {
|
20
|
+
if (SD_JWT.includes(format)) {
|
21
|
+
// 1. SD-JWT case
|
22
|
+
const decoded = decode(credential);
|
23
|
+
const jwk = decoded.sdJwt.payload.cnf.jwk;
|
24
|
+
if (jwk) {
|
25
|
+
return { ...jwk, kid: await thumbprint(jwk) };
|
26
|
+
}
|
27
|
+
}
|
28
|
+
throw new IoWalletError(`Credential format ${format} not supported`);
|
29
|
+
};
|
package/src/utils/crypto.ts
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
import {
|
2
|
-
getPublicKey,
|
3
|
-
sign,
|
4
|
-
generate,
|
5
2
|
deleteKey,
|
3
|
+
generate,
|
4
|
+
getPublicKeyFixed,
|
5
|
+
sign,
|
6
6
|
} from "@pagopa/io-react-native-crypto";
|
7
7
|
import { v4 as uuidv4 } from "uuid";
|
8
|
-
import {
|
9
|
-
import { fixBase64EncodingOnKey } from "./jwk";
|
8
|
+
import { type CryptoContext, thumbprint } from "@pagopa/io-react-native-jwt";
|
10
9
|
|
11
10
|
/**
|
12
11
|
* Create a CryptoContext bound to a key pair.
|
@@ -17,22 +16,15 @@ import { fixBase64EncodingOnKey } from "./jwk";
|
|
17
16
|
*/
|
18
17
|
export const createCryptoContextFor = (keytag: string): CryptoContext => {
|
19
18
|
return {
|
20
|
-
/**
|
21
|
-
* Retrieve the public key of the pair.
|
22
|
-
* If the key pair doesn't exist yet, an error is raised
|
23
|
-
* @returns The public key.
|
24
|
-
*/
|
25
19
|
async getPublicKey() {
|
26
|
-
return
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
kid: await thumbprint(jwk),
|
35
|
-
}));
|
20
|
+
return getPublicKeyFixed(keytag).then(async (jwk) => ({
|
21
|
+
...jwk,
|
22
|
+
// Keys in the TEE are not stored with their KID, which is supposed to be assigned when they are included in JWK sets.
|
23
|
+
// (that is, KID is not a propoerty of the key itself, but it's property used to identify a key in a set).
|
24
|
+
// We assume the convention we use the thumbprint of the public key as KID, thus for easy development we decided to evaluate KID here
|
25
|
+
// However the values is an arbitrary string that might be anything
|
26
|
+
kid: await thumbprint(jwk),
|
27
|
+
}));
|
36
28
|
},
|
37
29
|
/**
|
38
30
|
* Get a signature for a provided value.
|
package/src/utils/jwk.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { decode, removePadding } from "@pagopa/io-react-native-jwt";
|
1
|
+
import { decode, removePadding, thumbprint } from "@pagopa/io-react-native-jwt";
|
2
2
|
import { z } from "zod";
|
3
3
|
|
4
4
|
export type JWK = z.infer<typeof JWK>;
|
@@ -65,3 +65,17 @@ export const JWKS = z.object({
|
|
65
65
|
});
|
66
66
|
|
67
67
|
export type JWTDecodeResult = ReturnType<typeof decode>;
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Utility function that checks if two JWKs have the same thumbprint.
|
71
|
+
* @param jwkA The first JWK
|
72
|
+
* @param jwkB The second JWK
|
73
|
+
* @returns Whether the thumbprints match
|
74
|
+
*/
|
75
|
+
export const isSameThumbprint = async (jwkA: JWK, jwkB: JWK) => {
|
76
|
+
const [thumbprintJwkA, thumbprintJwkB] = await Promise.all([
|
77
|
+
thumbprint(jwkA),
|
78
|
+
thumbprint(jwkB),
|
79
|
+
]);
|
80
|
+
return thumbprintJwkA === thumbprintJwkB;
|
81
|
+
};
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"names":["_misc","require","_ioReactNativeJwt","_uuid","_types","_errors","_logging","statusAttestation","issuerConf","credential","credentialCryptoContext","appFetch","arguments","length","undefined","fetch","jwk","getPublicKey","credentialHash","getCredentialHashWithouDiscloures","statusAttUrl","openid_credential_issuer","status_attestation_endpoint","credentialPop","SignJWT","setPayload","aud","jti","uuidv4","toString","credential_hash","credential_hash_alg","setProtectedHeader","alg","typ","kid","setIssuedAt","setExpirationTime","sign","body","credential_pop","Logger","log","LogLevel","DEBUG","result","method","headers","JSON","stringify","then","hasStatusOrThrow","raw","json","StatusAttestationResponse","parse","catch","handleStatusAttestationError","status_attestation","exports","e","UnexpectedStatusCodeError","ResponseErrorBuilder","IssuerResponseError","handle","code","IssuerResponseErrorCodes","CredentialInvalidStatus","message","StatusAttestationRequestFailed","buildFrom"],"sourceRoot":"../../../../src","sources":["credential/status/02-status-attestation.ts"],"mappings":";;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AAMA,IAAAC,iBAAA,GAAAD,OAAA;AACA,IAAAE,KAAA,GAAAF,OAAA;AACA,IAAAG,MAAA,GAAAH,OAAA;AACA,IAAAI,OAAA,GAAAJ,OAAA;AAMA,IAAAK,QAAA,GAAAL,OAAA;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMM,iBAAoC,GAAG,eAAAA,CAClDC,UAAU,EACVC,UAAU,EACVC,uBAAuB,EAEpB;EAAA,IADHC,QAA8B,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAGG,KAAK;EAEtC,MAAMC,GAAG,GAAG,MAAMN,uBAAuB,CAACO,YAAY,CAAC,CAAC;EACxD,MAAMC,cAAc,GAAG,MAAM,IAAAC,uCAAiC,EAACV,UAAU,CAAC;EAC1E,MAAMW,YAAY,GAChBZ,UAAU,CAACa,wBAAwB,CAACC,2BAA2B;EACjE,MAAMC,aAAa,GAAG,MAAM,IAAIC,yBAAO,CAACd,uBAAuB,CAAC,CAC7De,UAAU,CAAC;IACVC,GAAG,EAAEN,YAAY;IACjBO,GAAG,EAAE,IAAAC,QAAM,EAAC,CAAC,CAACC,QAAQ,CAAC,CAAC;IACxBC,eAAe,EAAEZ,cAAc;IAC/Ba,mBAAmB,EAAE;EACvB,CAAC,CAAC,CACDC,kBAAkB,CAAC;IAClBC,GAAG,EAAE,OAAO;IACZC,GAAG,EAAE,gCAAgC;IACrCC,GAAG,EAAEnB,GAAG,CAACmB;EACX,CAAC,CAAC,CACDC,WAAW,CAAC,CAAC,CACbC,iBAAiB,CAAC,IAAI,CAAC,CACvBC,IAAI,CAAC,CAAC;EAET,MAAMC,IAAI,GAAG;IACXC,cAAc,EAAEjB;EAClB,CAAC;EAEDkB,eAAM,CAACC,GAAG,CAACC,iBAAQ,CAACC,KAAK,EAAG,mBAAkBrB,aAAc,EAAC,CAAC;EAE9D,MAAMsB,MAAM,GAAG,MAAMlC,QAAQ,CAACS,YAAY,EAAE;IAC1C0B,MAAM,EAAE,MAAM;IACdC,OAAO,EAAE;MACP,cAAc,EAAE;IAClB,CAAC;IACDR,IAAI,EAAES,IAAI,CAACC,SAAS,CAACV,IAAI;EAC3B,CAAC,CAAC,CACCW,IAAI,CAAC,IAAAC,sBAAgB,EAAC,GAAG,CAAC,CAAC,CAC3BD,IAAI,CAAEE,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC,CACzBH,IAAI,CAAEG,IAAI,IAAKC,gCAAyB,CAACC,KAAK,CAACF,IAAI,CAAC,CAAC,CACrDG,KAAK,CAACC,4BAA4B,CAAC;EAEtC,OAAO;IAAElD,iBAAiB,EAAEsC,MAAM,CAACa;EAAmB,CAAC;AACzD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AALAC,OAAA,CAAApD,iBAAA,GAAAA,iBAAA;AAMA,MAAMkD,4BAA4B,GAAIG,CAAU,IAAK;EACnD,IAAI,EAAEA,CAAC,YAAYC,iCAAyB,CAAC,EAAE;IAC7C,MAAMD,CAAC;EACT;EAEA,MAAM,IAAIE,4BAAoB,CAACC,2BAAmB,CAAC,CAChDC,MAAM,CAAC,GAAG,EAAE;IACXC,IAAI,EAAEC,gCAAwB,CAACC,uBAAuB;IACtDC,OAAO,EAAE;EACX,CAAC,CAAC,CACDJ,MAAM,CAAC,GAAG,EAAE;IACXC,IAAI,EAAEC,gCAAwB,CAACG,8BAA8B;IAC7DD,OAAO,EAAG;EACZ,CAAC,CAAC,CACDE,SAAS,CAACV,CAAC,CAAC;AACjB,CAAC"}
|
@@ -1,55 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
4
|
-
value: true
|
5
|
-
});
|
6
|
-
exports.verifyAndParseStatusAttestation = void 0;
|
7
|
-
var _errors = require("../../utils/errors");
|
8
|
-
var _ioReactNativeJwt = require("@pagopa/io-react-native-jwt");
|
9
|
-
var _types = require("./types");
|
10
|
-
var _logging = require("../../utils/logging");
|
11
|
-
/**
|
12
|
-
* Given a status attestation, verifies that:
|
13
|
-
* - It's in the supported format;
|
14
|
-
* - The attestation is correctly signed;
|
15
|
-
* - It's bound to the given key.
|
16
|
-
* @param issuerConf The Issuer configuration returned by {@link evaluateIssuerTrust}
|
17
|
-
* @param statusAttestation The encoded status attestation returned by {@link statusAttestation}
|
18
|
-
* @param context.credentialCryptoContext The crypto context used to obtain the credential in {@link obtainCredential}
|
19
|
-
* @returns A parsed status attestation
|
20
|
-
* @throws {IoWalletError} If the credential signature is not verified with the Issuer key set
|
21
|
-
* @throws {IoWalletError} If the credential is not bound to the provided user key
|
22
|
-
* @throws {IoWalletError} If the credential data fail to parse
|
23
|
-
*/
|
24
|
-
const verifyAndParseStatusAttestation = async (issuerConf, rawStatusAttestation, context) => {
|
25
|
-
try {
|
26
|
-
const {
|
27
|
-
statusAttestation
|
28
|
-
} = rawStatusAttestation;
|
29
|
-
const {
|
30
|
-
credentialCryptoContext
|
31
|
-
} = context;
|
32
|
-
await (0, _ioReactNativeJwt.verify)(statusAttestation, issuerConf.openid_credential_issuer.jwks.keys);
|
33
|
-
const decodedJwt = (0, _ioReactNativeJwt.decode)(statusAttestation);
|
34
|
-
const parsedStatusAttestation = _types.ParsedStatusAttestation.parse({
|
35
|
-
header: decodedJwt.protectedHeader,
|
36
|
-
payload: decodedJwt.payload
|
37
|
-
});
|
38
|
-
_logging.Logger.log(_logging.LogLevel.DEBUG, `Parsed status attestation: ${JSON.stringify(parsedStatusAttestation)}`);
|
39
|
-
const holderBindingKey = await credentialCryptoContext.getPublicKey();
|
40
|
-
const {
|
41
|
-
cnf
|
42
|
-
} = parsedStatusAttestation.payload;
|
43
|
-
if (!cnf.jwk.kid || cnf.jwk.kid !== holderBindingKey.kid) {
|
44
|
-
_logging.Logger.log(_logging.LogLevel.ERROR, `Failed to verify holder binding for status attestation, expected kid: ${holderBindingKey.kid}, got: ${parsedStatusAttestation.payload.cnf.jwk.kid}`);
|
45
|
-
throw new _errors.IoWalletError(`Failed to verify holder binding for status attestation, expected kid: ${holderBindingKey.kid}, got: ${parsedStatusAttestation.payload.cnf.jwk.kid}`);
|
46
|
-
}
|
47
|
-
return {
|
48
|
-
parsedStatusAttestation
|
49
|
-
};
|
50
|
-
} catch (e) {
|
51
|
-
throw new _errors.IoWalletError(`Failed to verify status attestation: ${JSON.stringify(e)}`);
|
52
|
-
}
|
53
|
-
};
|
54
|
-
exports.verifyAndParseStatusAttestation = verifyAndParseStatusAttestation;
|
55
|
-
//# sourceMappingURL=03-verify-and-parse-status-attestation.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"names":["_errors","require","_ioReactNativeJwt","_types","_logging","verifyAndParseStatusAttestation","issuerConf","rawStatusAttestation","context","statusAttestation","credentialCryptoContext","verify","openid_credential_issuer","jwks","keys","decodedJwt","decodeJwt","parsedStatusAttestation","ParsedStatusAttestation","parse","header","protectedHeader","payload","Logger","log","LogLevel","DEBUG","JSON","stringify","holderBindingKey","getPublicKey","cnf","jwk","kid","ERROR","IoWalletError","e","exports"],"sourceRoot":"../../../../src","sources":["credential/status/03-verify-and-parse-status-attestation.ts"],"mappings":";;;;;;AACA,IAAAA,OAAA,GAAAC,OAAA;AACA,IAAAC,iBAAA,GAAAD,OAAA;AAEA,IAAAE,MAAA,GAAAF,OAAA;AAEA,IAAAG,QAAA,GAAAH,OAAA;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMI,+BAAgE,GAC3E,MAAAA,CAAOC,UAAU,EAAEC,oBAAoB,EAAEC,OAAO,KAAK;EACnD,IAAI;IACF,MAAM;MAAEC;IAAkB,CAAC,GAAGF,oBAAoB;IAClD,MAAM;MAAEG;IAAwB,CAAC,GAAGF,OAAO;IAE3C,MAAM,IAAAG,wBAAM,EACVF,iBAAiB,EACjBH,UAAU,CAACM,wBAAwB,CAACC,IAAI,CAACC,IAC3C,CAAC;IAED,MAAMC,UAAU,GAAG,IAAAC,wBAAS,EAACP,iBAAiB,CAAC;IAC/C,MAAMQ,uBAAuB,GAAGC,8BAAuB,CAACC,KAAK,CAAC;MAC5DC,MAAM,EAAEL,UAAU,CAACM,eAAe;MAClCC,OAAO,EAAEP,UAAU,CAACO;IACtB,CAAC,CAAC;IAEFC,eAAM,CAACC,GAAG,CACRC,iBAAQ,CAACC,KAAK,EACb,8BAA6BC,IAAI,CAACC,SAAS,CAACX,uBAAuB,CAAE,EACxE,CAAC;IAED,MAAMY,gBAAgB,GAAG,MAAMnB,uBAAuB,CAACoB,YAAY,CAAC,CAAC;IACrE,MAAM;MAAEC;IAAI,CAAC,GAAGd,uBAAuB,CAACK,OAAO;IAC/C,IAAI,CAACS,GAAG,CAACC,GAAG,CAACC,GAAG,IAAIF,GAAG,CAACC,GAAG,CAACC,GAAG,KAAKJ,gBAAgB,CAACI,GAAG,EAAE;MACxDV,eAAM,CAACC,GAAG,CACRC,iBAAQ,CAACS,KAAK,EACb,yEAAwEL,gBAAgB,CAACI,GAAI,UAAShB,uBAAuB,CAACK,OAAO,CAACS,GAAG,CAACC,GAAG,CAACC,GAAI,EACrJ,CAAC;MACD,MAAM,IAAIE,qBAAa,CACpB,yEAAwEN,gBAAgB,CAACI,GAAI,UAAShB,uBAAuB,CAACK,OAAO,CAACS,GAAG,CAACC,GAAG,CAACC,GAAI,EACrJ,CAAC;IACH;IAEA,OAAO;MAAEhB;IAAwB,CAAC;EACpC,CAAC,CAAC,OAAOmB,CAAC,EAAE;IACV,MAAM,IAAID,qBAAa,CACpB,wCAAuCR,IAAI,CAACC,SAAS,CAACQ,CAAC,CAAE,EAC5D,CAAC;EACH;AACF,CAAC;AAACC,OAAA,CAAAhC,+BAAA,GAAAA,+BAAA"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"names":["getCredentialHashWithouDiscloures","hasStatusOrThrow","SignJWT","v4","uuidv4","StatusAttestationResponse","IssuerResponseError","IssuerResponseErrorCodes","ResponseErrorBuilder","UnexpectedStatusCodeError","LogLevel","Logger","statusAttestation","issuerConf","credential","credentialCryptoContext","appFetch","arguments","length","undefined","fetch","jwk","getPublicKey","credentialHash","statusAttUrl","openid_credential_issuer","status_attestation_endpoint","credentialPop","setPayload","aud","jti","toString","credential_hash","credential_hash_alg","setProtectedHeader","alg","typ","kid","setIssuedAt","setExpirationTime","sign","body","credential_pop","log","DEBUG","result","method","headers","JSON","stringify","then","raw","json","parse","catch","handleStatusAttestationError","status_attestation","e","handle","code","CredentialInvalidStatus","message","StatusAttestationRequestFailed","buildFrom"],"sourceRoot":"../../../../src","sources":["credential/status/02-status-attestation.ts"],"mappings":"AAAA,SACEA,iCAAiC,EACjCC,gBAAgB,QAEX,kBAAkB;AAEzB,SAA6BC,OAAO,QAAQ,6BAA6B;AACzE,SAASC,EAAE,IAAIC,MAAM,QAAQ,MAAM;AACnC,SAASC,yBAAyB,QAAQ,SAAS;AACnD,SACEC,mBAAmB,EACnBC,wBAAwB,EACxBC,oBAAoB,EACpBC,yBAAyB,QACpB,oBAAoB;AAC3B,SAASC,QAAQ,EAAEC,MAAM,QAAQ,qBAAqB;AAWtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,iBAAoC,GAAG,eAAAA,CAClDC,UAAU,EACVC,UAAU,EACVC,uBAAuB,EAEpB;EAAA,IADHC,QAA8B,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAGG,KAAK;EAEtC,MAAMC,GAAG,GAAG,MAAMN,uBAAuB,CAACO,YAAY,CAAC,CAAC;EACxD,MAAMC,cAAc,GAAG,MAAMvB,iCAAiC,CAACc,UAAU,CAAC;EAC1E,MAAMU,YAAY,GAChBX,UAAU,CAACY,wBAAwB,CAACC,2BAA2B;EACjE,MAAMC,aAAa,GAAG,MAAM,IAAIzB,OAAO,CAACa,uBAAuB,CAAC,CAC7Da,UAAU,CAAC;IACVC,GAAG,EAAEL,YAAY;IACjBM,GAAG,EAAE1B,MAAM,CAAC,CAAC,CAAC2B,QAAQ,CAAC,CAAC;IACxBC,eAAe,EAAET,cAAc;IAC/BU,mBAAmB,EAAE;EACvB,CAAC,CAAC,CACDC,kBAAkB,CAAC;IAClBC,GAAG,EAAE,OAAO;IACZC,GAAG,EAAE,gCAAgC;IACrCC,GAAG,EAAEhB,GAAG,CAACgB;EACX,CAAC,CAAC,CACDC,WAAW,CAAC,CAAC,CACbC,iBAAiB,CAAC,IAAI,CAAC,CACvBC,IAAI,CAAC,CAAC;EAET,MAAMC,IAAI,GAAG;IACXC,cAAc,EAAEf;EAClB,CAAC;EAEDhB,MAAM,CAACgC,GAAG,CAACjC,QAAQ,CAACkC,KAAK,EAAG,mBAAkBjB,aAAc,EAAC,CAAC;EAE9D,MAAMkB,MAAM,GAAG,MAAM7B,QAAQ,CAACQ,YAAY,EAAE;IAC1CsB,MAAM,EAAE,MAAM;IACdC,OAAO,EAAE;MACP,cAAc,EAAE;IAClB,CAAC;IACDN,IAAI,EAAEO,IAAI,CAACC,SAAS,CAACR,IAAI;EAC3B,CAAC,CAAC,CACCS,IAAI,CAACjD,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAC3BiD,IAAI,CAAEC,GAAG,IAAKA,GAAG,CAACC,IAAI,CAAC,CAAC,CAAC,CACzBF,IAAI,CAAEE,IAAI,IAAK/C,yBAAyB,CAACgD,KAAK,CAACD,IAAI,CAAC,CAAC,CACrDE,KAAK,CAACC,4BAA4B,CAAC;EAEtC,OAAO;IAAE3C,iBAAiB,EAAEiC,MAAM,CAACW;EAAmB,CAAC;AACzD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,MAAMD,4BAA4B,GAAIE,CAAU,IAAK;EACnD,IAAI,EAAEA,CAAC,YAAYhD,yBAAyB,CAAC,EAAE;IAC7C,MAAMgD,CAAC;EACT;EAEA,MAAM,IAAIjD,oBAAoB,CAACF,mBAAmB,CAAC,CAChDoD,MAAM,CAAC,GAAG,EAAE;IACXC,IAAI,EAAEpD,wBAAwB,CAACqD,uBAAuB;IACtDC,OAAO,EAAE;EACX,CAAC,CAAC,CACDH,MAAM,CAAC,GAAG,EAAE;IACXC,IAAI,EAAEpD,wBAAwB,CAACuD,8BAA8B;IAC7DD,OAAO,EAAG;EACZ,CAAC,CAAC,CACDE,SAAS,CAACN,CAAC,CAAC;AACjB,CAAC"}
|
@@ -1,49 +0,0 @@
|
|
1
|
-
import { IoWalletError } from "../../utils/errors";
|
2
|
-
import { verify } from "@pagopa/io-react-native-jwt";
|
3
|
-
import { ParsedStatusAttestation } from "./types";
|
4
|
-
import { decode as decodeJwt } from "@pagopa/io-react-native-jwt";
|
5
|
-
import { LogLevel, Logger } from "../../utils/logging";
|
6
|
-
/**
|
7
|
-
* Given a status attestation, verifies that:
|
8
|
-
* - It's in the supported format;
|
9
|
-
* - The attestation is correctly signed;
|
10
|
-
* - It's bound to the given key.
|
11
|
-
* @param issuerConf The Issuer configuration returned by {@link evaluateIssuerTrust}
|
12
|
-
* @param statusAttestation The encoded status attestation returned by {@link statusAttestation}
|
13
|
-
* @param context.credentialCryptoContext The crypto context used to obtain the credential in {@link obtainCredential}
|
14
|
-
* @returns A parsed status attestation
|
15
|
-
* @throws {IoWalletError} If the credential signature is not verified with the Issuer key set
|
16
|
-
* @throws {IoWalletError} If the credential is not bound to the provided user key
|
17
|
-
* @throws {IoWalletError} If the credential data fail to parse
|
18
|
-
*/
|
19
|
-
export const verifyAndParseStatusAttestation = async (issuerConf, rawStatusAttestation, context) => {
|
20
|
-
try {
|
21
|
-
const {
|
22
|
-
statusAttestation
|
23
|
-
} = rawStatusAttestation;
|
24
|
-
const {
|
25
|
-
credentialCryptoContext
|
26
|
-
} = context;
|
27
|
-
await verify(statusAttestation, issuerConf.openid_credential_issuer.jwks.keys);
|
28
|
-
const decodedJwt = decodeJwt(statusAttestation);
|
29
|
-
const parsedStatusAttestation = ParsedStatusAttestation.parse({
|
30
|
-
header: decodedJwt.protectedHeader,
|
31
|
-
payload: decodedJwt.payload
|
32
|
-
});
|
33
|
-
Logger.log(LogLevel.DEBUG, `Parsed status attestation: ${JSON.stringify(parsedStatusAttestation)}`);
|
34
|
-
const holderBindingKey = await credentialCryptoContext.getPublicKey();
|
35
|
-
const {
|
36
|
-
cnf
|
37
|
-
} = parsedStatusAttestation.payload;
|
38
|
-
if (!cnf.jwk.kid || cnf.jwk.kid !== holderBindingKey.kid) {
|
39
|
-
Logger.log(LogLevel.ERROR, `Failed to verify holder binding for status attestation, expected kid: ${holderBindingKey.kid}, got: ${parsedStatusAttestation.payload.cnf.jwk.kid}`);
|
40
|
-
throw new IoWalletError(`Failed to verify holder binding for status attestation, expected kid: ${holderBindingKey.kid}, got: ${parsedStatusAttestation.payload.cnf.jwk.kid}`);
|
41
|
-
}
|
42
|
-
return {
|
43
|
-
parsedStatusAttestation
|
44
|
-
};
|
45
|
-
} catch (e) {
|
46
|
-
throw new IoWalletError(`Failed to verify status attestation: ${JSON.stringify(e)}`);
|
47
|
-
}
|
48
|
-
};
|
49
|
-
//# sourceMappingURL=03-verify-and-parse-status-attestation.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"names":["IoWalletError","verify","ParsedStatusAttestation","decode","decodeJwt","LogLevel","Logger","verifyAndParseStatusAttestation","issuerConf","rawStatusAttestation","context","statusAttestation","credentialCryptoContext","openid_credential_issuer","jwks","keys","decodedJwt","parsedStatusAttestation","parse","header","protectedHeader","payload","log","DEBUG","JSON","stringify","holderBindingKey","getPublicKey","cnf","jwk","kid","ERROR","e"],"sourceRoot":"../../../../src","sources":["credential/status/03-verify-and-parse-status-attestation.ts"],"mappings":"AACA,SAASA,aAAa,QAAQ,oBAAoB;AAClD,SAASC,MAAM,QAA4B,6BAA6B;AAExE,SAASC,uBAAuB,QAAQ,SAAS;AACjD,SAASC,MAAM,IAAIC,SAAS,QAAQ,6BAA6B;AACjE,SAASC,QAAQ,EAAEC,MAAM,QAAQ,qBAAqB;AAUtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,+BAAgE,GAC3E,MAAAA,CAAOC,UAAU,EAAEC,oBAAoB,EAAEC,OAAO,KAAK;EACnD,IAAI;IACF,MAAM;MAAEC;IAAkB,CAAC,GAAGF,oBAAoB;IAClD,MAAM;MAAEG;IAAwB,CAAC,GAAGF,OAAO;IAE3C,MAAMT,MAAM,CACVU,iBAAiB,EACjBH,UAAU,CAACK,wBAAwB,CAACC,IAAI,CAACC,IAC3C,CAAC;IAED,MAAMC,UAAU,GAAGZ,SAAS,CAACO,iBAAiB,CAAC;IAC/C,MAAMM,uBAAuB,GAAGf,uBAAuB,CAACgB,KAAK,CAAC;MAC5DC,MAAM,EAAEH,UAAU,CAACI,eAAe;MAClCC,OAAO,EAAEL,UAAU,CAACK;IACtB,CAAC,CAAC;IAEFf,MAAM,CAACgB,GAAG,CACRjB,QAAQ,CAACkB,KAAK,EACb,8BAA6BC,IAAI,CAACC,SAAS,CAACR,uBAAuB,CAAE,EACxE,CAAC;IAED,MAAMS,gBAAgB,GAAG,MAAMd,uBAAuB,CAACe,YAAY,CAAC,CAAC;IACrE,MAAM;MAAEC;IAAI,CAAC,GAAGX,uBAAuB,CAACI,OAAO;IAC/C,IAAI,CAACO,GAAG,CAACC,GAAG,CAACC,GAAG,IAAIF,GAAG,CAACC,GAAG,CAACC,GAAG,KAAKJ,gBAAgB,CAACI,GAAG,EAAE;MACxDxB,MAAM,CAACgB,GAAG,CACRjB,QAAQ,CAAC0B,KAAK,EACb,yEAAwEL,gBAAgB,CAACI,GAAI,UAASb,uBAAuB,CAACI,OAAO,CAACO,GAAG,CAACC,GAAG,CAACC,GAAI,EACrJ,CAAC;MACD,MAAM,IAAI9B,aAAa,CACpB,yEAAwE0B,gBAAgB,CAACI,GAAI,UAASb,uBAAuB,CAACI,OAAO,CAACO,GAAG,CAACC,GAAG,CAACC,GAAI,EACrJ,CAAC;IACH;IAEA,OAAO;MAAEb;IAAwB,CAAC;EACpC,CAAC,CAAC,OAAOe,CAAC,EAAE;IACV,MAAM,IAAIhC,aAAa,CACpB,wCAAuCwB,IAAI,CAACC,SAAS,CAACO,CAAC,CAAE,EAC5D,CAAC;EACH;AACF,CAAC"}
|
@@ -1,19 +0,0 @@
|
|
1
|
-
import { type Out } from "../../utils/misc";
|
2
|
-
import type { EvaluateIssuerTrust, ObtainCredential } from "../issuance";
|
3
|
-
import { type CryptoContext } from "@pagopa/io-react-native-jwt";
|
4
|
-
import { StatusAttestationResponse } from "./types";
|
5
|
-
export type StatusAttestation = (issuerConf: Out<EvaluateIssuerTrust>["issuerConf"], credential: Out<ObtainCredential>["credential"], credentialCryptoContext: CryptoContext, appFetch?: GlobalFetch["fetch"]) => Promise<{
|
6
|
-
statusAttestation: StatusAttestationResponse["status_attestation"];
|
7
|
-
}>;
|
8
|
-
/**
|
9
|
-
* WARNING: This function must be called after {@link startFlow}.
|
10
|
-
* Verify the status of the credential attestation.
|
11
|
-
* @param issuerConf - The issuer's configuration
|
12
|
-
* @param credential - The credential to be verified
|
13
|
-
* @param credentialCryptoContext - The credential's crypto context
|
14
|
-
* @param context.appFetch (optional) fetch api implementation. Default: built-in fetch
|
15
|
-
* @throws {IssuerResponseError} with a specific code for more context
|
16
|
-
* @returns The credential status attestation
|
17
|
-
*/
|
18
|
-
export declare const statusAttestation: StatusAttestation;
|
19
|
-
//# sourceMappingURL=02-status-attestation.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"02-status-attestation.d.ts","sourceRoot":"","sources":["../../../../src/credential/status/02-status-attestation.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,GAAG,EACT,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,KAAK,aAAa,EAAW,MAAM,6BAA6B,CAAC;AAE1E,OAAO,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AASpD,MAAM,MAAM,iBAAiB,GAAG,CAC9B,UAAU,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,EAClD,UAAU,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC,YAAY,CAAC,EAC/C,uBAAuB,EAAE,aAAa,EACtC,QAAQ,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,KAC5B,OAAO,CAAC;IACX,iBAAiB,EAAE,yBAAyB,CAAC,oBAAoB,CAAC,CAAC;CACpE,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,iBA6C/B,CAAC"}
|
@@ -1,24 +0,0 @@
|
|
1
|
-
import type { Out } from "../../utils/misc";
|
2
|
-
import { type CryptoContext } from "@pagopa/io-react-native-jwt";
|
3
|
-
import type { EvaluateIssuerTrust, StatusAttestation } from "../status";
|
4
|
-
import { ParsedStatusAttestation } from "./types";
|
5
|
-
export type VerifyAndParseStatusAttestation = (issuerConf: Out<EvaluateIssuerTrust>["issuerConf"], statusAttestation: Out<StatusAttestation>, context: {
|
6
|
-
credentialCryptoContext: CryptoContext;
|
7
|
-
}) => Promise<{
|
8
|
-
parsedStatusAttestation: ParsedStatusAttestation;
|
9
|
-
}>;
|
10
|
-
/**
|
11
|
-
* Given a status attestation, verifies that:
|
12
|
-
* - It's in the supported format;
|
13
|
-
* - The attestation is correctly signed;
|
14
|
-
* - It's bound to the given key.
|
15
|
-
* @param issuerConf The Issuer configuration returned by {@link evaluateIssuerTrust}
|
16
|
-
* @param statusAttestation The encoded status attestation returned by {@link statusAttestation}
|
17
|
-
* @param context.credentialCryptoContext The crypto context used to obtain the credential in {@link obtainCredential}
|
18
|
-
* @returns A parsed status attestation
|
19
|
-
* @throws {IoWalletError} If the credential signature is not verified with the Issuer key set
|
20
|
-
* @throws {IoWalletError} If the credential is not bound to the provided user key
|
21
|
-
* @throws {IoWalletError} If the credential data fail to parse
|
22
|
-
*/
|
23
|
-
export declare const verifyAndParseStatusAttestation: VerifyAndParseStatusAttestation;
|
24
|
-
//# sourceMappingURL=03-verify-and-parse-status-attestation.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"03-verify-and-parse-status-attestation.d.ts","sourceRoot":"","sources":["../../../../src/credential/status/03-verify-and-parse-status-attestation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAU,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAIlD,MAAM,MAAM,+BAA+B,GAAG,CAC5C,UAAU,EAAE,GAAG,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,EAClD,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,CAAC,EACzC,OAAO,EAAE;IACP,uBAAuB,EAAE,aAAa,CAAC;CACxC,KACE,OAAO,CAAC;IAAE,uBAAuB,EAAE,uBAAuB,CAAA;CAAE,CAAC,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,+BAA+B,EAAE,+BAwC3C,CAAC"}
|
@@ -1,70 +0,0 @@
|
|
1
|
-
import type { Out } from "../../utils/misc";
|
2
|
-
import { IoWalletError } from "../../utils/errors";
|
3
|
-
import { verify, type CryptoContext } from "@pagopa/io-react-native-jwt";
|
4
|
-
import type { EvaluateIssuerTrust, StatusAttestation } from "../status";
|
5
|
-
import { ParsedStatusAttestation } from "./types";
|
6
|
-
import { decode as decodeJwt } from "@pagopa/io-react-native-jwt";
|
7
|
-
import { LogLevel, Logger } from "../../utils/logging";
|
8
|
-
|
9
|
-
export type VerifyAndParseStatusAttestation = (
|
10
|
-
issuerConf: Out<EvaluateIssuerTrust>["issuerConf"],
|
11
|
-
statusAttestation: Out<StatusAttestation>,
|
12
|
-
context: {
|
13
|
-
credentialCryptoContext: CryptoContext;
|
14
|
-
}
|
15
|
-
) => Promise<{ parsedStatusAttestation: ParsedStatusAttestation }>;
|
16
|
-
|
17
|
-
/**
|
18
|
-
* Given a status attestation, verifies that:
|
19
|
-
* - It's in the supported format;
|
20
|
-
* - The attestation is correctly signed;
|
21
|
-
* - It's bound to the given key.
|
22
|
-
* @param issuerConf The Issuer configuration returned by {@link evaluateIssuerTrust}
|
23
|
-
* @param statusAttestation The encoded status attestation returned by {@link statusAttestation}
|
24
|
-
* @param context.credentialCryptoContext The crypto context used to obtain the credential in {@link obtainCredential}
|
25
|
-
* @returns A parsed status attestation
|
26
|
-
* @throws {IoWalletError} If the credential signature is not verified with the Issuer key set
|
27
|
-
* @throws {IoWalletError} If the credential is not bound to the provided user key
|
28
|
-
* @throws {IoWalletError} If the credential data fail to parse
|
29
|
-
*/
|
30
|
-
export const verifyAndParseStatusAttestation: VerifyAndParseStatusAttestation =
|
31
|
-
async (issuerConf, rawStatusAttestation, context) => {
|
32
|
-
try {
|
33
|
-
const { statusAttestation } = rawStatusAttestation;
|
34
|
-
const { credentialCryptoContext } = context;
|
35
|
-
|
36
|
-
await verify(
|
37
|
-
statusAttestation,
|
38
|
-
issuerConf.openid_credential_issuer.jwks.keys
|
39
|
-
);
|
40
|
-
|
41
|
-
const decodedJwt = decodeJwt(statusAttestation);
|
42
|
-
const parsedStatusAttestation = ParsedStatusAttestation.parse({
|
43
|
-
header: decodedJwt.protectedHeader,
|
44
|
-
payload: decodedJwt.payload,
|
45
|
-
});
|
46
|
-
|
47
|
-
Logger.log(
|
48
|
-
LogLevel.DEBUG,
|
49
|
-
`Parsed status attestation: ${JSON.stringify(parsedStatusAttestation)}`
|
50
|
-
);
|
51
|
-
|
52
|
-
const holderBindingKey = await credentialCryptoContext.getPublicKey();
|
53
|
-
const { cnf } = parsedStatusAttestation.payload;
|
54
|
-
if (!cnf.jwk.kid || cnf.jwk.kid !== holderBindingKey.kid) {
|
55
|
-
Logger.log(
|
56
|
-
LogLevel.ERROR,
|
57
|
-
`Failed to verify holder binding for status attestation, expected kid: ${holderBindingKey.kid}, got: ${parsedStatusAttestation.payload.cnf.jwk.kid}`
|
58
|
-
);
|
59
|
-
throw new IoWalletError(
|
60
|
-
`Failed to verify holder binding for status attestation, expected kid: ${holderBindingKey.kid}, got: ${parsedStatusAttestation.payload.cnf.jwk.kid}`
|
61
|
-
);
|
62
|
-
}
|
63
|
-
|
64
|
-
return { parsedStatusAttestation };
|
65
|
-
} catch (e) {
|
66
|
-
throw new IoWalletError(
|
67
|
-
`Failed to verify status attestation: ${JSON.stringify(e)}`
|
68
|
-
);
|
69
|
-
}
|
70
|
-
};
|