Skip to content

Commit 06d7cc4

Browse files
authored
Fix/sl-verification (#332)
Signed-off-by: Mirko Mollik <[email protected]>
1 parent ed8b7d0 commit 06d7cc4

File tree

5 files changed

+40
-17
lines changed

5 files changed

+40
-17
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './status-list';
2+
export * from './status-list-exception';
23
export * from './status-list-jwt';
34
export * from './types';
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* SLException is a custom error class for Status List related exceptions.
3+
*/
4+
export class SLException extends Error {
5+
public details?: unknown;
6+
7+
constructor(message: string, details?: unknown) {
8+
super(message);
9+
Object.setPrototypeOf(this, SLException.prototype);
10+
this.name = 'SLException';
11+
this.details = details;
12+
}
13+
14+
getFullMessage(): string {
15+
return `${this.name}: ${this.message} ${
16+
this.details ? `- ${JSON.stringify(this.details)}` : ''
17+
}`;
18+
}
19+
}

packages/jwt-status-list/src/status-list-jwt.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { JwtPayload } from '@sd-jwt/types';
22
import { base64urlDecode } from '@sd-jwt/utils';
33
import { StatusList } from './status-list';
4+
import { SLException } from './status-list-exception';
45
import type {
56
JWTwithStatusListPayload,
67
StatusListEntry,
@@ -33,13 +34,13 @@ export function createHeaderAndPayload(
3334
// validate if the required fieds are present based on https://www.ietf.org/archive/id/draft-ietf-oauth-status-list-02.html#section-5.1
3435

3536
if (!payload.iss) {
36-
throw new Error('iss field is required');
37+
throw new SLException('iss field is required');
3738
}
3839
if (!payload.sub) {
39-
throw new Error('sub field is required');
40+
throw new SLException('sub field is required');
4041
}
4142
if (!payload.iat) {
42-
throw new Error('iat field is required');
43+
throw new SLException('iat field is required');
4344
}
4445
//exp and tll are optional. We will not validate the business logic of the values like exp > iat etc.
4546

packages/jwt-status-list/src/status-list.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { base64UrlToUint8Array, uint8ArrayToBase64Url } from '@sd-jwt/utils';
22
import { deflate, inflate } from 'pako';
3+
import { SLException } from './status-list-exception';
34
import type { BitsPerStatus } from './types';
45
/**
56
* StatusListManager is a class that manages a list of statuses with variable bit size.
@@ -16,12 +17,12 @@ export class StatusList {
1617
*/
1718
constructor(statusList: number[], bitsPerStatus: BitsPerStatus) {
1819
if (![1, 2, 4, 8].includes(bitsPerStatus)) {
19-
throw new Error('bitsPerStatus must be 1, 2, 4, or 8');
20+
throw new SLException('bitsPerStatus must be 1, 2, 4, or 8');
2021
}
2122
//check that the entries in the statusList are within the range of the bitsPerStatus
2223
for (let i = 0; i < statusList.length; i++) {
2324
if (statusList[i] > 2 ** bitsPerStatus) {
24-
throw Error(
25+
throw new SLException(
2526
`Status value out of range at index ${i} with value ${statusList[i]}`,
2627
);
2728
}

packages/sd-jwt-vc/src/sd-jwt-vc-instance.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Jwt, SDJwt, SDJwtInstance, type VerifierOptions } from '@sd-jwt/core';
22
import {
33
getListFromStatusListJWT,
4+
SLException,
45
type StatusListJWTHeaderParameters,
56
type StatusListJWTPayload,
67
} from '@sd-jwt/jwt-status-list';
@@ -306,18 +307,18 @@ export class SDJwtVcInstance extends SDJwtInstance<SdJwtVcPayload> {
306307
StatusListJWTPayload
307308
>(statusListJWT);
308309
// check if the status list has a valid signature. The presence of the verifier is checked in the parent class.
309-
await slJWT.verify(
310-
this.userConfig.statusVerifier ??
311-
(this.userConfig.verifier as Verifier),
312-
options,
313-
);
314-
315-
const currentDate =
316-
options?.currentDate ?? Math.floor(Date.now() / 1000);
317-
//check if the status list is expired
318-
if (slJWT.payload?.exp && (slJWT.payload.exp as number) < currentDate) {
319-
throw new SDJWTException('Status list is expired');
320-
}
310+
await slJWT
311+
.verify(
312+
this.userConfig.statusVerifier ??
313+
(this.userConfig.verifier as Verifier),
314+
options,
315+
)
316+
.catch((err: SLException) => {
317+
throw new SLException(
318+
`Status List JWT verification failed: ${err.message}`,
319+
err.details,
320+
);
321+
});
321322

322323
// get the status list from the status list JWT
323324
const statusList = getListFromStatusListJWT(statusListJWT);

0 commit comments

Comments
 (0)